问答

关于useRef的一点疑惑

作者:admin 2021-04-22 我要评论

今天碰到一道面试题目,题目是关于React中useRef的使用,代码如下: const App = ()={ const [count, setCount] = useState(0); const lastCount = useRef(count...

在说正事之前,我要推荐一个福利:你还在原价购买阿里云、腾讯云、华为云服务器吗?那太亏啦!来这里,新购、升级、续费都打折,能够为您省60%的钱呢!2核4G企业级云服务器低至69元/年,点击进去看看吧>>>)

今天碰到一道面试题目,题目是关于React中useRef的使用,代码如下:

const App = ()=>{
    const [count, setCount] = useState(0);
    const lastCount = useRef(count);
    useEffect(()=>{
      lastCount.current = count;  
    })
    function handleAlertClick(){
        setTimeout(()=>{
            alert(lastCount.current)
        },3000);
    }
    return <div>
        <p>你点击了{count}次</p>
        <button onClick={()=>setCount(count+1)}>click me</button>
        <button onClick={handleAlertClick}> show Alert</button>
    </div>
}
ReactDOM.render(
    <App />,
    document.getElementById('root')
);

image.png

问题是:多次点击第一个按钮,中途点击一下第二个按钮,然后再点击第一个按钮,弹窗弹出的数字是什么样的,解释一下流程。

###

每次弹出来都是最新的值,流程就是setCount之后触发rerender,然后count变更了,useEffect由于没有指定依赖所以每次rerender都会重新执行,故而每次ref都是最新值,如果useEffect依赖为空数组则每次都是0

###

useState和useEffect的问题

useState触发更新,useEffect每次渲染后调用

setTimeout和useRef的问题

明白上一点后,我们跳出react简化一下, 其实就是

for (var i = 0; i < 10; i++) {
    //定义lastCount
    lastCount.current = i
    setTimeout(() => {
        console.log(lastCount.current)
    }, 3000)
}

这个经典(烂大街)的问题,用var或者let会有不同的结果,原因是作用域不同;
那么useRef属于哪一种呢,useRef返回的对象在组件的生命周期保持不变,和var是一样的;
这里alert(lastCount.current)改成alert(count),结果就会变成和let一样,因为useState每次更新都会有一个”副本“

版权声明:本文转载自网络,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本站转载出于传播更多优秀技术知识之目的,如有侵权请联系QQ/微信:153890879删除

相关文章
  • 关于useRef的一点疑惑

    关于useRef的一点疑惑

  • ng-zorro的nz-selected组件所有的事件

    ng-zorro的nz-selected组件所有的事件

  • MySQL索引失效,先记录下

    MySQL索引失效,先记录下

  • 使用rsync同步文件时, 如何根据文件的

    使用rsync同步文件时, 如何根据文件的

腾讯云代理商
海外云服务器