我有一个带有手柄功能的表格。
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);
}
如果我在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,第二个记录中断。
答案 0 :(得分:4)
事件值通过react清除。您需要使用event.persist来保留事件值,或存储事件中的值以供以后使用
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);
}