我们使用Backbone + ReactJS捆绑包来构建客户端应用程序。严重依赖臭名昭著的是,valueLink我们通过自己的支持ReactJS接口进行双向绑定的包装器将值直接传播到模型。
valueLink
现在我们面对这个问题:
我们有一个jquery.mask.js插件,可以通过编程方式格式化输入值,因此不会触发React事件。当模型从用户输入中接收 未格式化的 值而从插件中 丢失格式化的 值时,所有这些都会导致情况。
jquery.mask.js
似乎React依赖于浏览器有很多事件处理策略。有什么通用的方法可以触发特定DOM元素的change事件,以便React可以听到吗?
对于React 16和React > = 15.6
设置.value=器无法正常工作,因为React库会覆盖输入值设置器,但是我们可以直接在inputas上下文中调用该函数。
.value=
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元素,你应该使用prototype的HTMLTextAreaElement类。
prototype
HTMLTextAreaElement
新的codepen示例。
所有学分这个贡献者和他的解决方案
仅适用于React <= 15.5的过时答案
有了react-dom ^15.6.0您可以使用simulated标志事件对象的事件经过
react-dom ^15.6.0
simulated
var ev = new Event('input', { bubbles: true}); ev.simulated = true; element.value = 'Something new'; element.dispatchEvent(ev);
我用一个例子做了一个codepen
为了理解为什么需要新标记,我发现此注释非常有帮助:
现在,React中的输入逻辑对重复事件的重复事件进行重复数据删除,因此每个值不会触发多次。它侦听浏览器的onChange / onInput事件以及DOM节点值prop上的设置(当您通过javascript更新值时)。这具有副作用,即如果您手动更新输入的值,则input.value =’foo’然后使用{target:input}分派一个ChangeEvent React将同时注册集合和事件,看到它的值仍然是’‘foo ‘,将其视为重复事件并吞下。 在正常情况下,这可以正常工作,因为浏览器启动的“真实”事件不会触发element.value上的设置。您可以通过使用模拟标志标记触发的事件来暗中逃避此逻辑,并且反应将始终触发该事件。 https://github.com/jquense/react/blob/9a93af4411a8e880bbc05392ccf2b195c97502d1/src/renderers/dom/client/eventPlugins/ChangeEventPlugin.js#L128
现在,React中的输入逻辑对重复事件的重复事件进行重复数据删除,因此每个值不会触发多次。它侦听浏览器的onChange / onInput事件以及DOM节点值prop上的设置(当您通过javascript更新值时)。这具有副作用,即如果您手动更新输入的值,则input.value =’foo’然后使用{target:input}分派一个ChangeEvent React将同时注册集合和事件,看到它的值仍然是’‘foo ‘,将其视为重复事件并吞下。
在正常情况下,这可以正常工作,因为浏览器启动的“真实”事件不会触发element.value上的设置。您可以通过使用模拟标志标记触发的事件来暗中逃避此逻辑,并且反应将始终触发该事件。 https://github.com/jquense/react/blob/9a93af4411a8e880bbc05392ccf2b195c97502d1/src/renderers/dom/client/eventPlugins/ChangeEventPlugin.js#L128