**注意:我对这个问题的回答很差。起初我想问别的问题,但既然发生了这种情况,我就把唯一的答案标记为正确。
我尝试为通过更改输入值触发的操作添加延迟。我需要在用户将最后一个字符写入输入2秒后触发此操作。
首先,我试着写了这样的东西:
onChange={(e) => {
const timeoutFn = setTimeout(() => {
// This func triggers rerender of the component
onInputChange(e.target.value);
}, 2000);
return () => clearTimeout(timeoutFn);
}}
这种方法不起作用,所以我使用了useEffect
,它工作得很好。但是,现在我对onChange
的处理程序中setTimout
的奇怪行为感兴趣。
当我在onChange
中使用setTimeout
时,onInputChange
在用户开始键入后的2秒内仅触发一次。同时,e.target.value
包含用户输入的最后一个值。
为什么它是这样工作的,而不是像setTimout
在useEffect
中工作的那样?
1条答案
按热度按时间sdnqo3pr1#
但是,现在我对
onChange
的处理程序中setTimout
的奇怪行为感兴趣。对于React,当前代码没有发生任何事情,就好像它是
onChange={(e) => {}}
,因为状态是 * 不 * 立即更新,这意味着重新渲染是 * 不发生,e.target.value
仍然是""
。(* 注意 *:even0
ms不会立即更新状态,因为setTimeout
的异步特性以及事件循环的工作方式(您可以查看下面的链接)。当我在
onChange
中使用setTimeout
时,onInputChange
在用户开始输入后的2秒内只触发 * 一次 *。它实际上并不是只触发一次,
setTimeout
的回调在 *2秒 (2000 ms)后运行,其次数与在input
中输入的字符数相同( 即使input
没有更新 )。您可以通过在setTimeout
的回调fn中调用console.count('callback fired')
来验证这一点。同时,
e.target.value
包含用户输入的最后一个值。是的,如果你在
onChange
中使用console.log(e.target.value)
,它确实会在用户输入字符时打印最后输入的字符,但由于update not happening意味着React组件 not re-rendering意味着input
的value
prop仍然是 initial value。当setTimeout
的 delay 过去( 2000 ms )时,回调函数被调用,然后onInputChange(e.target.value)
被调用,其中e.target.value
等于""
( 空字符串 * 或任何初始值),所以发生的事情是这样的:onInputChange("")
被调用,当React没有看到任何变化时,重新渲染 * 不会发生。顺便说一句,你不需要
return () => clearTimeout(timeoutFn)
,因为它什么也不做;如果你打算clearTimeout(timeoutFn)
(有或没有return
)setTimeout
将不会运行,因为它将被清除(* 取消 *)之前,其 * 延迟 * 已经完成.你可以看到我的代码示例:
。
关于Event Loop的链接: