React: 在离散事件中设置状态是否会导致清理运行?

创建于 2019-03-05  ·  3评论  ·  资料来源: facebook/react

这个错误非常令人困惑:

https://twitter.com/kentcdodds/status/1102659818660102145

我想这是因为fn按计划setInterval(fn, 0)在前面跳跃[running]造成的影响清理setRunning(false) 。 所以间隔仍是起火,覆盖setLapse(0)其在活动期间所发生setLapse(someValue)

这让我想起了https://github.com/facebook/react/issues/14750#issuecomment -460409609 中描述的问题,或者至少是其中的一部分:

事实上,即使对于常规的 React 击键(和其他“离散”事件),这个问题也存在。 解决方案是在我们获得离散事件之前清除被动效果。

但在这里,好像因为效果翻转点击setState也应该刷新被动效果? 好像没有。 (这将违背拖延他们的目的。)

所以这是按设计工作的,当时间很重要时,修复只是useLayoutEffect ? 还是 rAF 解决方案?

Hooks Question

最有用的评论

一种方法是仅在计时器实际停止时(即在效果中)才调度重置。 如果你想让它在同一帧中始终显示零,那么你可以在运行为false时始终显示零。

然而,与往常一样,这更好地建模为减速器。 当 reducer 认为它处于停止状态时,它可以很容易地拒绝更新失效,并执行逻辑来实际重置它。

所有3条评论

问题是计时器本身不是一个离散事件。 离散事件仅在与其他离散事件相关时得到保证。 我不认为这就是你想要的。

停止计时器是一个异步操作,因为所有设置的状态都是异步的。 所以其他东西可以在它被冲洗之前进入。

在这种情况下 useLayoutEffect 实际上并没有完全解决问题。 当然不是在并发模式下,但这在同步模式下也是粗略的。 如果它不是一个计时器,而是一个焦点事件,那么它可以在刷新之前在批处理中触发,这将具有相同的问题。

setRunning(false); // I would like to add a stop of this timer to the queue to be performed later
setLapse(0); // I would like to add an operation to set lapse to zero later
// lots of random stuff that can happen before the batch flushes
// This might also queue an operation to set lapse to something else
// actual rendering
// If concurrent mode, lots of other random stuff that can happen while rendering
// This might also queue an operation to set lapse to something else
// Actually do all that work in order

一切都与将事物添加到队列中的顺序有关。

一种方法是仅在计时器实际停止时(即在效果中)才调度重置。 如果你想让它在同一帧中始终显示零,那么你可以在运行为false时始终显示零。

然而,与往常一样,这更好地建模为减速器。 当 reducer 认为它处于停止状态时,它可以很容易地拒绝更新失效,并执行逻辑来实际重置它。

此页面是否有帮助?
0 / 5 - 0 等级