为什么 <form> 上的 onChange 事件处理程序从 <select> 中获取分派的事件,而不是 <input>?
Why does the onChange event handler on <form> pick upp dispatched events from <select>, but not <input>?
我正在用 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;
希望对您有所帮助。
祝你有美好的一天,新年快乐!
我正在用 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;
希望对您有所帮助。 祝你有美好的一天,新年快乐!