V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
cjc2017
V2EX  ›  问与答

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

  •  
  •   cjc2017 · 2019-05-13 15:29:27 +08:00 · 4057 次点击
    这是一个创建于 2025 天前的主题,其中的信息可能已经有所发展或是发生改变。
    使用 react hook 写倒计时的 demo 中发现 setTime 更新 time 值时必须要用函数返回值 如果直接使用 setTime(time-1)更新后的值一直为 59 大概猜到的可能是由于闭包引起的 在定时器内部执行 setTime 时 time 总是 60
    具体代码见: https://codepen.io/anon/pen/LoRpEv
    11 条回复    2019-05-13 21:35:17 +08:00
    rookiebulls
        1
    rookiebulls  
       2019-05-13 15:39:10 +08:00 via iPhone   ❤️ 1
    猜测是异步引起的
    momocraft
        2
    momocraft  
       2019-05-13 15:55:25 +08:00   ❤️ 1
    没有得到 useState 的语义,建议读一下 dan abramov 那几篇 blog,从 https://overreacted.io/react-as-a-ui-runtime/ 开始
    momocraft
        3
    momocraft  
       2019-05-13 15:56:18 +08:00   ❤️ 1
    btw 这个 setInterval 要泄漏的,你可能还需要看 useEffect
    cjc2017
        4
    cjc2017  
    OP
       2019-05-13 16:02:12 +08:00
    @rookiebulls 也怀疑过是异步线程导致的 但是第一次调用 setTime(time-1)时页面可以正常渲染成 59 定时器是延迟了 1000ms 也没有其他的代码逻辑 react 这块的事件队列应该是都执行完了的
    cjc2017
        5
    cjc2017  
    OP
       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
        6
    momocraft  
       2019-05-13 16:17:03 +08:00   ❤️ 1
    @cjc2017 const time 是个 **const** ,其实每次打 log 会比感觉可靠点
    cjc2017
        7
    cjc2017  
    OP
       2019-05-13 16:36:39 +08:00
    @momocraft 其实也有输出 log 每次输出的都是 60 我应该是需要了解一下 const 定义的 time 变量和页面中渲染的变量差异 以及在 setTime 中都大概发生了什么 多谢了老哥
    coldsnap
        8
    coldsnap  
       2019-05-13 16:54:28 +08:00   ❤️ 1
    https://codepen.io/anon/pen/PvGbbv
    你需要清除 interval
    cjc2017
        9
    cjc2017  
    OP
       2019-05-13 17:07:42 +08:00
    @coldsnap 老哥 我未删减前的代码几乎和你的一摸一样 连变量名 off 都一样[捂脸] 不过我困惑的是为什么在 setInterval 中不能直接 setTime(time-1)必须要 setTime(t => t -1)这种写法
    vigossliao
        10
    vigossliao  
       2019-05-13 19:04:05 +08:00   ❤️ 1
    闭包的问题
    ```
    // 这里 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
        11
    cjc2017  
    OP
       2019-05-13 21:35:17 +08:00
    @vigossliao 看完后 受益匪浅 多谢多谢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4945 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 03:59 · PVG 11:59 · LAX 19:59 · JFK 22:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.