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

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

问题描述

我们使用 Backbone + ReactJS 包来构建客户端应用程序.严重依赖臭名昭著的 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 库覆盖了输入值设置器,但我们可以直接在 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/onInputDOM 节点值属性上的事件和集合(当您更新通过 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://github.com/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

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

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