React函数组件中如何在自定义函数内获取更新后的state值?
问题核心
React的setState是异步更新状态的,在同一个函数执行栈里,状态不会立刻生效。你在useEffect中调用GetData()后马上执行ShowData(data),此时data还是useEffect闭包捕获的初始值[];而组件外部的console.log(data)是在状态更新触发组件重新渲染后执行的,所以能拿到最新的[1,2,3]。
解决方法
方法一:直接传递新数据给ShowData
既然在GetData里已经明确要设置的新数据,直接在setData之后把这个值传给ShowData即可,省去依赖状态的麻烦:
function Foo() { const [data, setData] = useState([]); const GetData = () => { const newData = [1, 2, 3]; setData(newData); ShowData(newData); // 直接传入刚定义的新数据 } const ShowData = (data) => { if(data) console.log(data); } useEffect( () => { GetData(); },[]); console.log(data); return ( <> <h2>Hello world ! </h2> </> )}
方法二:用useEffect监听data的变化
新增一个useEffect,将data作为依赖项,每当data更新时自动触发ShowData:
function Foo() { const [data, setData] = useState([]); const GetData = () => { setData([1, 2, 3]); } const ShowData = (data) => { if(data) console.log(data); } // 仅在组件初始化时调用GetData useEffect( () => { GetData(); },[]); // 监听data的变化,状态更新时执行ShowData useEffect( () => { ShowData(data); },[data]); // 依赖数组添加data,确保状态变化时触发 console.log(data); return ( <> <h2>Hello world ! </h2> </> )}
方法三:用useRef保存最新状态(适配复杂异步场景)
如果你的业务场景涉及定时器、异步回调等复杂逻辑,需要随时获取最新状态,可以用useRef来同步保存最新的data值:
function Foo() { const [data, setData] = useState([]); const dataRef = useRef(data); // 每次data更新时同步更新ref的current值 useEffect(() => { dataRef.current = data; }, [data]); const GetData = () => { setData([1, 2, 3]); } const ShowData = () => { if(dataRef.current) console.log(dataRef.current); // 从ref中获取最新状态 } useEffect( () => { GetData(); // 由于setState异步,这里用setTimeout确保能拿到更新后的ref值 setTimeout(() => { ShowData(); }, 0); },[]); console.log(data); return ( <> <h2>Hello world ! </h2> </> )}
日常开发中,方法一和方法二足以解决绝大多数类似问题,可根据实际业务需求选择。
内容的提问来源于stack exchange,提问作者ahmed nadjib
相关产品推荐
相关产品推荐

