React中自定义change事件无法触发onChange prop的问题排查
自定义change/input事件无法触发React input的onChange prop问题
问题描述
我正在测试tagger库的新版本,代码中会在input元素上分发自定义change事件:
this._input.dispatchEvent(new Event('change', { bubbles: true }));
但触发该事件时,React组件中input的onChange prop并未被触发。
以下是测试用的React组件代码:
const App = () => { const [tags, setTags] = useState(null) const inputRef = useRef(null) useEffect(() => { const taggerOptions = { allow_spaces: true, } inputRef.current.addEventListener('change', (e) => { console.log(e); }); tagger(inputRef.current, taggerOptions) }, []); const onChange = (e) => { setTags(e.target.value) }; return ( <div className="app"> <input type="text" ref={inputRef} onChange={onChange} defaultValue="charles, louis, michel" /> {tags && <pre>{tags}</pre>} </div> ) }
运行后发现,原生addEventListener绑定的change事件会执行(console.log输出内容),但React的onChange回调setTags完全没触发。
想知道:是否有办法让自定义事件触发React的onChange={}回调?如果无法实现,麻烦解释原因,是否有官方文档说明仅原生用户触发的事件才能触发React的onChange?
补充尝试
之前尝试过React中触发input/change事件的常见解决方案,但没有效果——我的问题不是值更新异常,而是事件完全没触发,哪怕值设置错误也是如此。
我已将如下代码加入tagger库(库使用ES5编写,未升级到现代JS):
_update_input: function () { // ReactJS overwrite value setting on inputs, this is a workaround var inputProto = window.HTMLInputElement.prototype; var nativeInputValueSetter = Object.getOwnPropertyDescriptor(inputProto, "value").set; nativeInputValueSetter.call(this._input, this._tags.join(',')); this._input.dispatchEvent(new Event('input', { bubbles: true })); },
测试后该方案仍未生效,但原解决方案的Demo是可以正常运行的,问题到底出在哪里?
我甚至写了独立的测试代码,手动触发事件,结果React的onChange还是没触发:
const App = () => { const [value, setValue] = useState('charles, louis, michel'); const inputRef = useRef(null); const tags = tags_array(value); useEffect(() => { const taggerOptions = { allow_spaces: true, }; tagger(inputRef.current, taggerOptions); }, [inputRef]); const onChange = (event) => { setValue(event.target.value); }; const trigger = () => { const input = inputRef.current; var nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set; nativeInputValueSetter.call(input, 'one, two, three'); input.dispatchEvent(new Event('input', { bubbles: true })); }; return ( <div className="app"> <input type="text" value={value} ref={inputRef} onChange={onChange} /> <br/> <ul> {tags.map((tag, index) => <li key={`${tag}-${index}`}>{tag}</li>)} </ul> <button onClick={trigger}>trigger change event</button> </div> ) }
另外,我把原解决方案改成了React 18+Hooks版本,该版本能正常运行——事件触发逻辑在React内部时是有效的。
内容的提问来源于stack exchange,提问作者jcubic
相关产品推荐
相关产品推荐

