#问题
当异步获取useState声明的state变量时,如果异步期间state发生了改变,异步操作仍引用旧的的state值
下例中,在调用getCountSync的3s延时中,如果点击了add按钮,打印的结果仍是未点击的。
jsximport { useState } from 'react' function App() { const [count, setCount] = useState(0) const add = () => { setCount(count + 1) } const getCountSync = () => { setTimeout(() => { console.log('count', count) }, 3000) } return ( <> <p>{count}</p> <button onClick={add}>add</button> <button onClick={getCountSync}>getCount</button> </> ) }
#原因
在React中,当state发生改变时,jsx函数会重新执行
而在渲染期间执行的函数(异步函数),会去捕获当时变量值的快照,而非最新的状态值
#利用useRef来解决
因为useRef是用于存储一个不变的值,并且ref.current的值在整个组件生命周期中都不变,所以可以通过useRef来存储最新的useState的值
jsximport { useEffect, useRef, useState } from 'react' function App() { const [count, setCount] = useState(0) const countRef = useRef(0) useEffect(() => { countRef.current = count }, [count]) const add = () => { setCount(count + 1) } const getCountSync = () => { setTimeout(() => { // console.log('count', count) alert(countRef.current) }, 3000) } return ( <> <p>{count}</p> <button onClick={add}>add</button> <button onClick={getCountSync}>getCount</button> </> ) }