我正在 React 中构建一个具有许多复杂表单的应用程序,并且我尝试在 <form>
上使用 onChange 事件处理程序元素。
<form onChange={handleChange}>
<input name="input1" />
<input name="input2" />
...
</form>
这在监听常规 HTML 输入的变化时效果很好,但在构建 <CustomInput>
时效果很好。 ,我无法触发 <form>
上的 onChange .
我创建了一个“隐藏”<input>
并手动调度 Event("change")
,但它没有被 <form>
上的 onChange 拾取。 ,但是,它确实适用于 <select>
输入。
import { useRef } from "react";
function App() {
const inpRef = useRef();
const selRef = useRef();
function onChange(e) {
console.log(e.target.name); // Only "select" is logged
}
function dispatchChange() {
inpRef.current.dispatchEvent(new Event("change", { bubbles: true }));
selRef.current.dispatchEvent(new Event("change", { bubbles: true }));
}
return (
<>
<form onChange={onChange}>
<input ref={inpRef} name="input" />
<select ref={selRef} name="select" />
</form>
<button onClick={dispatchChange}>Trigger change</button>
</>
);
}
export default App;
为什么 <select>
会发生“更改”事件触发 onChange,但不触发 <input>
?
最佳答案
发生此问题是因为输入的“更改事件”非常特殊。它由“ChangeEventPlugin”管理。
此插件的限制之一是仅当输入值实际更改时才会调度“change”事件。
要解决该问题,您必须在代码中添加以下内容:
useEffect(() => {
inpRef.current._valueTracker.getValue = () => {
return 'fake value'
}
}, []);
当然,还要导入“useEffect”。
import { useEffect, useRef } from 'react';
所以,最后,完整的代码将是:
import { useEffect, useRef } from 'react';
function App() {
const inpRef = useRef();
const selRef = useRef();
function onChange(e) {
console.log(e.target.name); // Only "select" is logged
}
function dispatchChange() {
inpRef.current.dispatchEvent(new Event("change", { bubbles: true }));
selRef.current.dispatchEvent(new Event("change", { bubbles: true }));
}
useEffect(() => {
inpRef.current._valueTracker.getValue = () => {
return 'fake value'
}
}, []);
return (
<>
<form onChange={onChange}>
<input ref={inpRef} name="input" />
<select ref={selRef} name="select" />
</form>
<button onClick={dispatchChange}>Trigger change</button>
</>
);
}
export default App;
希望对您有帮助。 祝你有美好的一天,新年快乐!
关于javascript - 为什么 <form> 上的 onChange 事件处理程序从 <select> 获取分派(dispatch)的事件,而不是从 <input> 获取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70549260/