在react js中触发onchange事件的最佳方法是什么 [英] What is the best way to trigger onchange event in react js

查看:303
本文介绍了在react js中触发onchange事件的最佳方法是什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们使用 Backbone + ReactJS bundle 构建客户端应用程序.严重依赖臭名昭著的 valueLink,我们通过自己的包装器将值直接传播到模型,该包装器支持 ReactJS 接口进行双向绑定.

We use Backbone + ReactJS bundle to build a client-side app. Heavily relying on notorious valueLink we propagate values directly to the model via own wrapper that supports ReactJS interface for two way binding.

现在我们遇到了问题:

我们有 jquery.mask.js 插件,它以编程方式格式化输入值,因此它不会触发 React 事件.所有这些都会导致模型从用户输入中接收未格式化的值,而从插件中错过格式化的值.

We have jquery.mask.js plugin which formats input value programmatically thus it doesn't fire React events. All this leads to situation when model receives unformatted values from user input and misses formatted ones from plugin.

React 似乎有很多取决于浏览器的事件处理策略.有没有什么通用的方法可以触发特定 DOM 元素的更改事件,以便 React 听到它?

It seems that React has plenty of event handling strategies depending on browser. Is there any common way to trigger change event for particular DOM element so that React will hear it?

推荐答案

对于 React 16 和 React >=15.6

Setter .value= 没有像我们想要的那样工作,因为 React 库覆盖了输入值 setter,但我们可以直接在 input 作为上下文调用该函数.

Setter .value= is not working as we wanted because React library overrides input value setter but we can call the function directly on the input as context.

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.

For textarea element you should use prototype of HTMLTextAreaElement class.

新的 codepen 示例.

感谢此贡献者他的解决方案

仅适用于 React <=15.5

使用 react-dom ^15.6.0 你可以在事件对象上使用 simulated 标志让事件通过

With react-dom ^15.6.0 you can use simulated flag on the event object for the event to pass through

var ev = new Event('input', { bubbles: true});
ev.simulated = true;
element.value = 'Something new';
element.dispatchEvent(ev);

我用一个例子做了一个codepen

I made a codepen with an example

要了解为什么需要新标志,我找到了此评论 很有帮助:

To understand why new flag is needed I found this comment very helpful:

React 中的输入逻辑现在对更改事件进行重复数据删除,因此它们不会触发每个值不止一次.它侦听浏览器 onChange/onInput事件以及 DOM 节点值道具上的设置(当您更新值通过javascript).这意味着如果你手动更新输入的值 input.value = 'foo' 然后调度一个ChangeEvent with { target: input } React 将注册这两个集合和事件,看到它的值仍然是''foo',认为它是重复的事件并吞下它.

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.

这在正常情况下工作正常,因为启动了真实"浏览器事件不会触发 element.value 上的设置.你可以保释这个逻辑是通过标记你用模拟触发的事件来秘密进行的flag 和 react 将始终触发事件.https://https://github.com/jquense/react/blob/9a93af4411a8e880bbc05392ccf2b195c97502d1/src/renderers/dom/client/eventPlugins/ChangeEventPlugin.js#L128/jquense/react/blob/9a93af4411a8e880bbc05392ccf2b195c97502d1/src/renderers/dom/client/eventPlugins/ChangeEventPlugin.js#L128

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

这篇关于在react js中触发onchange事件的最佳方法是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆