关于 react hook 中使用定时器设置值的一个问题

2019-05-13 15:29:27 +08:00
 cjc2017
使用 react hook 写倒计时的 demo 中发现 setTime 更新 time 值时必须要用函数返回值 如果直接使用 setTime(time-1)更新后的值一直为 59 大概猜到的可能是由于闭包引起的 在定时器内部执行 setTime 时 time 总是 60
具体代码见: https://codepen.io/anon/pen/LoRpEv
3872 次点击
所在节点    问与答
11 条回复
rookiebulls
2019-05-13 15:39:10 +08:00
猜测是异步引起的
momocraft
2019-05-13 15:55:25 +08:00
没有得到 useState 的语义,建议读一下 dan abramov 那几篇 blog,从 https://overreacted.io/react-as-a-ui-runtime/ 开始
momocraft
2019-05-13 15:56:18 +08:00
btw 这个 setInterval 要泄漏的,你可能还需要看 useEffect
cjc2017
2019-05-13 16:02:12 +08:00
@rookiebulls 也怀疑过是异步线程导致的 但是第一次调用 setTime(time-1)时页面可以正常渲染成 59 定时器是延迟了 1000ms 也没有其他的代码逻辑 react 这块的事件队列应该是都执行完了的
cjc2017
2019-05-13 16:10:21 +08:00
@momocraft 看过 dan abramov 讲 event loop 和 react hook 的视频 都讲的非常棒。个人感觉执行了 setTime 后 time 值应该是改变了 不过页面上渲染的 time 值和我 setTime(time-1)中的这个是不是同一个 就不清楚了 如果不是同一个的话 会不会在定时器中调用 setTime(time-1)的这个 time 一直都是初始化时的 60 ? useEffect 这个原来是有写的 为了方便看给删除掉了
momocraft
2019-05-13 16:17:03 +08:00
@cjc2017 const time 是个 **const** ,其实每次打 log 会比感觉可靠点
cjc2017
2019-05-13 16:36:39 +08:00
@momocraft 其实也有输出 log 每次输出的都是 60 我应该是需要了解一下 const 定义的 time 变量和页面中渲染的变量差异 以及在 setTime 中都大概发生了什么 多谢了老哥
coldsnap
2019-05-13 16:54:28 +08:00
https://codepen.io/anon/pen/PvGbbv
你需要清除 interval
cjc2017
2019-05-13 17:07:42 +08:00
@coldsnap 老哥 我未删减前的代码几乎和你的一摸一样 连变量名 off 都一样[捂脸] 不过我困惑的是为什么在 setInterval 中不能直接 setTime(time-1)必须要 setTime(t => t -1)这种写法
vigossliao
2019-05-13 19:04:05 +08:00
闭包的问题
```
// 这里 log 一下 time 一直等于 60
// 引用的是第一次 render 拿到的
setTime(time-1)
```
https://codepen.io/anon/pen/xNErpN?editors=1111


dan 的文章讲的很全了 https://overreacted.io/a-complete-guide-to-useeffect/
cjc2017
2019-05-13 21:35:17 +08:00
@vigossliao 看完后 受益匪浅 多谢多谢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/563674

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX