setTimeout函数在反应中导致类型错误

时间:2020-05-04 10:35:13

标签: javascript reactjs

我有一个带有手柄功能的表格。

handle函数有一个超时,这会引起一些问题。

 const timeOut = useRef(null);





const handleSearchChange = (e) => {
    // setSearchKey(e.target.value.toLowerCase().trim());

        clearTimeout(timeOut.current);
        timeOut.current = setTimeout(() => {
            setSearchKey(e.target.value.toLowerCase().trim());
        }, 500);
}

enter image description here

如果我在settimeout函数之外的console.log(e.target.value)正常工作,当我合并setTimeout函数时,它会中断。为什么会这样?

我试图将功能简化为:

const handleSearchChange = (e) => {
    // setSearchKey(e.target.value.toLowerCase().trim());
    console.log(e.target.value)
    setTimeout(() => {
        // setSearchKey(e.target.value.toLowerCase().trim());
        console.log(e.target.value)
    }, 500);
}

问题仍然存在。它记录第一个console.log,第二个记录中断。

2 个答案:

答案 0 :(得分:4)

事件值通过react清除。您需要使用event.persist来保留事件值,或存储事件中的值以供以后使用

根据react documentation

SyntheticEvent对象将被重用,并且所有属性将被 调用事件回调后将其无效。这是为了 性能原因。因此,您无法在 异步方式。

const handleSearchChange = (e) => {
    // setSearchKey(e.target.value.toLowerCase().trim());
        clearTimeout(timeOut.current);
        const value = e.target.value.toLowerCase().trim();
        timeOut.current = setTimeout(() => {
            setSearchKey(value);
        }, 500);
}

答案 1 :(得分:2)

这是因为react中的e事件对象是由react生成的综合事件对象,而不是由浏览器内部生成的本地事件对象。

为了防止一直分配新对象,将其设计为可重复使用的对象,这意味着其属性在发射后会被剥离,并为下一个事件重新分配。

因此,在您的情况下,由于您在发出该对象后在异步回调中重新访问了该对象,因此该对象已被“回收”,从而使其属性过时。要解决此问题,您可以预先在同步事件循环中保存所需的值,然后将其传递给异步回调。

handleSearchChange = (e) => {
    const value = e.target.value.toLowerCase().trim()

    clearTimeout(timeOut.current);
    timeOut.current = setTimeout(() => {
        setSearchKey(value);
    }, 500);
}