You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何在自定义Hook卸载时将状态保存到Context?

解决组件卸载时将状态保存到Context的自定义Hook问题

原代码的核心问题在于卸载时执行的useEffect清理函数存在闭包陷阱:

  • 依赖数组为空,导致清理函数捕获的是初始渲染时的上下文值,若key参数变化或setStateStore出现不稳定情况(虽然useState返回的更新函数通常稳定),会导致更新Context的操作失效
  • 虽用stateRef跟踪了最新状态,但缺少必要依赖的清理函数无法保证执行时的上下文环境正确

修改后的自定义Hook代码

function useSpecialState(defaultValue, key) {
  const { stateStore, setStateStore } = useContext(StateStoreContext);

  // 函数式初始化,避免每次渲染重复执行状态判断
  const [state, setState] = useState(() => {
    return stateStore[key] !== undefined ? stateStore[key] : defaultValue;
  });

  const stateRef = useRef(state);

  // 同步最新状态到ref,确保卸载时能获取当前值
  useEffect(() => {
    stateRef.current = state;
  }, [state]);

  // 卸载时保存状态到Context,添加必要依赖避免闭包问题
  useEffect(() => {
    return () => {
      setStateStore((prevStateStore) => ({
        ...prevStateStore,
        [key]: stateRef.current,
      }));
    };
  }, [setStateStore, key]); // 加入稳定的setStateStore和参数key作为依赖

  return [state, setState];
}

修改说明

  1. 函数式初始化优化:将useState的初始值改为函数形式,避免组件每次渲染都执行stateStore[key]的判断逻辑,提升性能
  2. 修复闭包问题:给卸载逻辑的useEffect添加setStateStore和key作为依赖:
    • setStateStore是useState返回的更新函数,本身始终稳定,不会触发额外的清理函数重建
    • key作为Hook的入参,确保清理函数使用的是当前组件对应的最新key值
  3. 保留按需保存逻辑:仅在组件卸载时执行Context更新,不会在每次状态变更时触发多余操作

额外修复提示

父组件StateStoreComponent中存在拼写错误:props. Children应改为props.children(小写c),否则无法正确渲染子元素。

内容的提问来源于stack exchange,提问作者Laczkó Örs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 22:15:09