v6路由缓存机制踩坑:页面刷新后状态丢失解决方案
最近在项目中将React Router从v5升级到v6,遇到了一个令人头疼的问题——页面刷新后组件状态丢失。这个问题在v5中并不存在,让我花了不少时间排查。
问题复现步骤
- 在路由组件中使用了useState管理组件状态
- 用户在页面中进行交互操作,状态发生变化
- 用户手动刷新页面或通过浏览器前进后退
- 页面重新渲染,但组件状态丢失,回到初始值
根本原因
在React Router v6中,路由组件的卸载和重新挂载机制发生了变化。当路由切换时,组件会被销毁并重新创建,这导致了状态的丢失。特别是使用<Routes>配合<Route>时,每次路由变更都会触发组件的完整生命周期。
解决方案
方案一:使用useLocation和useNavigate结合localStorage
const MyComponent = () => {
const location = useLocation();
const navigate = useNavigate();
const [data, setData] = useState(() => {
// 从localStorage恢复状态
const saved = localStorage.getItem('myData');
return saved ? JSON.parse(saved) : initialState;
});
useEffect(() => {
// 每次状态变化时保存到localStorage
localStorage.setItem('myData', JSON.stringify(data));
}, [data]);
};
方案二:使用React Context进行状态管理
const StateContext = createContext();
const StateProvider = ({ children }) => {
const [state, setState] = useState(initialState);
return (
<StateContext.Provider value={{ state, setState }}>
{children}
</StateContext.Provider>
);
};
方案三:使用useEffect监听路由变化
const MyComponent = () => {
const [data, setData] = useState(initialState);
useEffect(() => {
// 监听路由变化,避免状态丢失
const handleRouteChange = () => {
// 保存当前状态
};
return () => {
// 清理函数
};
}, []);
};
建议在升级v6时提前规划好状态管理策略,避免类似问题影响用户体验。

讨论