react 中的 onChange 属性和自定义事件调度

onChange prop and custom Event dispatch in React

提问人:jcubic 提问时间:7/28/2023 最后编辑:Md. Rakibul Islamjcubic 更新时间:8/7/2023 访问量:262

问:

我正在测试我的库标记器的新版本,其中输入元素上有自定义事件调度:

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 和钩子从原始解决方案修改了 CodePen,并且该代码确实有效,即使事件的触发器像我的代码一样在 React 中。

javascript reactjs dom-events 自定义事件

评论


答:

1赞 Max 7/31/2023 #1

我在stackoverflow上找到了这个,你需要找到附加到DOM的react道具,并调用onChange函数

在react js中触发更改或输入事件的最佳方法是什么

评论

0赞 evolutionxbox 7/31/2023
请将问题标记为重复问题。
0赞 Max 7/31/2023
这个问题有一个开放的赏金,不能关闭
0赞 jcubic 8/2/2023
我已经编辑了问题,这不是重复的,因为在我的代码中没有触发事件。
2赞 jcubic 8/2/2023 #2

我已经找到了问题所在,我正在检查我的输入元素,似乎如果输入有事件,则不会在 ReactJS(或浏览器中,我不确定)。type="hidden"

评论

0赞 evolutionxbox 8/2/2023
stackoverflow.com/questions/1003053/......可能有关联吗?
0赞 David B 8/7/2023 #3

这对我来说最有效,触发器是一个没有 () 的对象,它是一个函数

onClick={() => trigger()}  

or if I want to pass the event then 

onClick{(e) => trigger(e)}

评论

0赞 jcubic 8/7/2023
这无济于事,因为我的元素被 CSS 隐藏了。我不确定这对任何人有什么帮助。