React自定义Hook调用useState后状态更新仍输出初始值问题
React闭包导致状态无法更新的问题解决
问题本质
这段代码里logState始终输出初始值true,核心原因是闭包捕获了旧的状态值:
组件首次渲染时,useEffect执行并捕获了当时的logState函数,这个函数绑定的是初始的state(true)。哪怕之后调用changeState把state改成false,已经被useEffect捕获的logState还是会引用最初的state值,所以2秒后执行时输出的还是旧值。另外你忽略了useEffect的依赖项检查,也导致它不会随着logState的更新重新执行。
可行解决方案
方案1:用useRef保存最新状态引用
在自定义Hook里通过useRef同步state的最新值,让logState总能拿到最新状态:
import { useState, useRef, useCallback } from 'react'; const useMyHook = () => { const [state, setState] = useState(true); const stateRef = useRef(state); // 实时同步state到ref stateRef.current = state; const changeState = () => { setState(false); }; const logState = useCallback(() => { console.log(stateRef.current); }, []); return { changeState, logState }; };
stateRef会始终指向最新的state值,不受闭包限制,logState调用时就能获取到更新后的状态。
方案2:让logState依赖state并更新useEffect依赖
去掉依赖项忽略注释,用useCallback包裹logState并依赖state,同时把logState加入useEffect的依赖数组:
import { useState, useCallback, useEffect } from 'react'; const useMyHook = () => { const [state, setState] = useState(true); const changeState = () => { setState(false); }; // state变化时更新logState const logState = useCallback(() => { console.log(state); }, [state]); return { changeState, logState }; }; function App() { const { changeState, logState } = useMyHook(); useEffect(() => { // 加个标志位防止重复执行changeState let isFirstRun = true; if (isFirstRun) { changeState(); const timer = setTimeout(logState, 2000); return () => clearTimeout(timer); } isFirstRun = false; }, [changeState, logState]); return <>...</> }
这种方式会让logState在state变化时更新,useEffect也会重新执行,注意要加标志位避免重复调用changeState。
方案3:直接在setState回调中获取最新状态
如果你的需求只是修改状态后记录最新值,可以直接在setState的函数式回调里操作,这里能直接拿到更新后的状态:
const useMyHook = () => { const [state, setState] = useState(true); const changeState = () => { setState(prevState => { const newState = false; console.log(newState); // 直接在这里输出最新状态 return newState; }); }; return { changeState }; };
这种方式最直接,不需要处理闭包问题,适合只需要在状态变更时记录的场景。
环境依赖
- Node Version: 18.14.2
- Yarn Version: 1.22.19
- React version: 18.2.0
内容的提问来源于stack exchange,提问作者Naveen Murali A V
相关产品推荐
相关产品推荐

