RA.*_*RA. 7 javascript dom-events typescript reactjs
我在 React 的输入字段中遇到了一个奇怪的问题。我知道hidden
输入不会触发input
或change
事件。然而,即使我手动触发它们,React 的onChange
事件仍然没有被调用。
我在这里同时触发change
和input
事件,因为 ReactonChange
实际上就是input
事件。当我在inputRef
( addEventListener("change", () => { ... })
)上设置事件侦听器以进行测试时,它被毫无问题地调用。然而,事实证明 React 在拦截它时遇到了一些问题。
这是我当前的代码:
const [fieldValue, setFieldValue] = useState(0);
const inputRef = useRef<HTMLInputElement>(null);
const handleClick = useCallback((): void => {
if (inputRef.current) {
inputRef.current.dispatchEvent(new Event("change", { bubbles: true }));
inputRef.current.dispatchEvent(new Event("input", { bubbles: true }));
}
setFieldValue(prev => prev + 1);
}, []);
Run Code Online (Sandbox Code Playgroud)
JSX:
<input type="hidden" ref={inputRef} value={fieldValue} onChange={(e) => { console.log("React:onChange"); }} />
<button type="button" onClick={handleClick}>Hit it</button>
Run Code Online (Sandbox Code Playgroud)
我在这里做错了什么吗?我还需要做什么才能正确触发 React 的onChange
事件?
React 中的事件由 react-dom 通过不同的插件处理。输入事件由SimpleEventPlugin管理(参见https://github.com/facebook/react/blob/master/packages/react-dom/src/events/SimpleEventPlugin.js)
这个插件获取一个事件并重新调度它而不会干扰太多。因此,您可以将它作为本机事件调度,并且它会作为SyntheticEvent触发而无需进行太多更改。
Change 事件由ChangeEventPlugin处理(参见https://github.com/facebook/react/blob/master/packages/react-dom/src/events/ChangeEventPlugin.js)。这个插件有这个目的:
该插件创建了一个
onChange
事件,用于规范跨表单元素的更改事件。当可以更改元素的值而不会看到闪烁时,会触发此事件。
该插件触发更改事件,但与本机更改事件不完全相同。例如,文本输入元素上的本机更改事件仅在模糊时触发。请参阅https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event
对于某些元素,包括 ,直到控件失去焦点才会触发更改事件。
但是对于 React,它在每次价值变化时都会以不同的方式触发。为此,它由具有以下限制的插件处理: 事件将仅在以下输入类型上触发:
color: true,
date: true,
datetime: true,
'datetime-local': true,
email: true,
month: true,
number: true,
password: true,
range: true,
search: true,
tel: true,
text: true,
time: true,
url: true,
week: true
Run Code Online (Sandbox Code Playgroud)
因此,对于隐藏的输入,react 会停止调度。
另一个限制是只有当输入的值实际发生变化时才会调度事件。看
if (updateValueIfChanged(targetNode)) {
return targetInst;
}
Run Code Online (Sandbox Code Playgroud)
因此,即使在受支持的输入上,您的调度也不会通过插件。您可以在此代码段中看到它,通过操作用于获取输入值的方法,您可以设法调度事件。
color: true,
date: true,
datetime: true,
'datetime-local': true,
email: true,
month: true,
number: true,
password: true,
range: true,
search: true,
tel: true,
text: true,
time: true,
url: true,
week: true
Run Code Online (Sandbox Code Playgroud)
if (updateValueIfChanged(targetNode)) {
return targetInst;
}
Run Code Online (Sandbox Code Playgroud)
所以对于一个隐藏的输入,没有办法让它工作(注意它是符合标准的)。对于文本(或其他支持的输入),您可以,但您需要或多或少地修改比较事件之前的值与事件之后的值的方法。
归档时间: |
|
查看次数: |
4922 次 |
最近记录: |