我正在测试我的库的新版本tagger,其中输入元素上有自定义事件调度:
this._input.dispatchEvent(new Event('change', { bubbles: true }));
问题是触发自定义事件时,不会触发该输入上的 onChange 属性。
const App = () => {
const [tags, setTags] = useState(null)
const inputRef = useRef(null)
// Write the Tagger code inside a useEffect hook
// It will run when the component is initially rendered
useEffect(() => {
// Define the Tagger options
const taggerOptions = {
allow_spaces: true,
}
inputRef.current.addEventListener('change', (e) => {
console.log(e);
});
// Initialize Tagger
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>
)
}
上面的代码中,console.log被执行了,但是setTags没有被执行。
有没有办法让输入时的自定义更改事件在默认事件
onChange={}
上触发?
如果这是不可能的,我可以解释原因。
这是否记录在只能使用本机事件的地方?
这是一个 CodePen 演示,可以在其中进行测试。
编辑
在 React js 中触发更改或输入事件的最佳方式是什么中的假设解决方案对我来说不起作用。该问题的问题不在于该值未正确更新,而是即使使用错误的值,该事件也根本没有触发。
我已将此代码添加到库中(对于 ES5 代码,抱歉,该库未更新为现代 JavaScript,我没有看到迁移的理由。代码工作正常):
_update_input: function () {
// ReactJS overwrite value setting on inputs, this is a workaround
// ref: https://stackoverflow.com/a/46012210/387194
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 }));
},
这里是我的实验性CodePen,它应该可以工作,但事实并非如此。我做错了什么?必须有一个简单的解释,因为带有原始解决方案的 CodePen 演示工作正常。
我什至添加了这段代码,但它仍然不起作用(事件未触发):
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 从原始解决方案中修改了 CodePen,并且该代码确实有效,即使事件的触发器像我的代码一样位于 React 内部。
我在stackoverflow上找到了这个,你需要找到附加到DOM的react props,并调用onChange函数
我发现了问题所在,我正在检查我的输入元素,似乎如果输入有
type="hidden"
,则事件不会在 ReactJS 中触发(或在浏览器中,我不确定)。