React自定义usePrevious钩子获取Context历史值始终返回最新值问题求助
问题排查与修复方案
核心错误点
- 自定义Hook
usePrevious定义在组件内部:函数组件每次重渲染都会重新执行整个函数体,内部定义的Hook会被反复初始化,对应的ref引用无法跨渲染周期存储历史值 - 自定义Hook
usePrevious定义在组件内部:函数组件每次重渲染都会重新执行整个函数体,内部定义的Hook会被反复初始化,对应的ref引用无法跨渲染周期存储历史值 - Context更新逻辑错误:代码中所有的
setMyPref调用都直接传入了原有myPref对象,没有生成新的对象引用,React基于引用比对判断状态是否变化,此时既不会触发Context订阅组件重渲染,也无法区分新旧值 - (非核心但需要优化点)
usePrevious内部的useEffect没有指定依赖数组,存在性能隐患
修复步骤
- 将
usePrevious移到组件外部定义,明确指定依赖项:
import React, { useRef, useEffect, useContext } from 'react' // 自定义Hook必须定义在组件外部 function usePrevious(value) { const ref = useRef(); // 仅当value变化时更新ref存储的值 useEffect(() => { ref.current = value; }, [value]); // 渲染阶段返回的是更新前的ref值,即上一次传入的value return ref.current; } function MyHeaderComponent(props) { // 原有组件逻辑 }
- 修正Context更新逻辑,所有状态更新必须传入新的对象引用:
// 错误写法,引用不变不会触发更新 setMyPref(myPref); // 正确写法,基于原有值生成新对象 setMyPref(prevPref => { return { ...prevPref, // 这里写你要修改的属性,比如修改preferences preferences: { ...prevPref.preferences, // 要更新的配置项示例 theme: 'dark' } } })
- 调整组件内useEffect逻辑,补充依赖项和边界判断:
const [myPref, setMyPref] = React.useContext(MyContext); const prevPreferences = usePrevious(myPref.preferences); useEffect(() => { // 跳过首次渲染的undefined判断,可根据业务需求调整 if (prevPreferences && prevPreferences !== myPref.preferences) { console.log("prevPreferences : ", prevPreferences); // 执行你的业务逻辑 myInfo(); } }, [myPref, prevPreferences]);
内容的提问来源于stack exchange,提问作者copenndthagen
相关产品推荐
相关产品推荐

