我们使用 Backbone + ReactJS bundle 来构建客户端应用程序。
我们严重依赖臭名昭著的 valueLink
,通过自己的包装器将值直接传播到模型,该包装器支持 ReactJS 接口(interface)进行双向绑定(bind)。
现在我们面临的问题是:
我们有jquery.mask.js
插件,它以编程方式格式化输入值,因此它不会触发React事件。所有这些都会导致模型从用户输入中接收到未格式化值,并从插件中错过格式化值。
React 似乎有很多取决于浏览器的事件处理策略。有没有通用的方法来触发特定 DOM 元素的更改事件,以便 React 能够听到它?
最佳答案
对于 React 16 和 React >=15.6
Setter .value=
没有按我们想要的方式工作,因为 React 库覆盖了输入值 setter,但我们可以直接在 input
作为上下文调用该函数。
var nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set;
nativeInputValueSetter.call(input, 'react 16 value');
var ev2 = new Event('input', { bubbles: true});
input.dispatchEvent(ev2);
对于 textarea 元素,您应该使用 HTMLTextAreaElement
类的 prototype
。
所有功劳归于this contributor和his solution
仅适用于 React <=15.5的过时答案
使用react-dom ^15.6.0
,您可以在事件对象上使用simulated
标志以使事件传递
var ev = new Event('input', { bubbles: true});
ev.simulated = true;
element.value = 'Something new';
element.dispatchEvent(ev);
为了理解为什么需要新标志,我发现了 this comment非常有帮助:
The input logic in React now dedupe's change events so they don't fire more than once per value. It listens for both browser onChange/onInput events as well as sets on the DOM node value prop (when you update the value via javascript). This has the side effect of meaning that if you update the input's value manually input.value = 'foo' then dispatch a ChangeEvent with { target: input } React will register both the set and the event, see it's value is still `'foo', consider it a duplicate event and swallow it.
This works fine in normal cases because a "real" browser initiated event doesn't trigger sets on the element.value. You can bail out of this logic secretly by tagging the event you trigger with a simulated flag and react will always fire the event. https://github.com/jquense/react/blob/9a93af4411a8e880bbc05392ccf2b195c97502d1/src/renderers/dom/client/eventPlugins/ChangeEventPlugin.js#L128
关于reactjs - 在react js中触发更改或输入事件的最佳方式是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23892547/