React Router v6中useNavigate(-1)回退时state为null及TS类型问题
React Router v6回退时的TypeScript类型问题与State传递解决方案
问题根源
你用navigate(-1 as To)绕过TypeScript类型错误的做法,本质是调用了NavigateFunction的路径跳转重载(接受To类型参数),而非回退重载(接受数字delta参数)。这会让React Router误把-1当作路径处理,即便最终实现了回退,传递的state也无法关联到历史栈里的上一页,所以useLocation()获取到的state始终为null。
修复TypeScript类型错误
不需要把-1断言为To,直接调用数字参数的重载即可。如果TS仍报错,可通过以下方式明确类型:
import { useNavigate } from 'react-router-dom'; const navigate = useNavigate(); // 直接调用回退重载,TS可自动推断类型 const goBack = () => navigate(-1); // 若仍有类型提示问题,显式指定参数类型 const goBackWithType = () => navigate(-1 as number);
回退时传递State的正确方案
React Router的回退操作是回到历史栈中已存在的页面条目,无法直接为该条目添加新state。若需让上一页获取状态,可采用以下两种方案:
方案1:全局状态管理
用React上下文(Context)或全局状态库(如Zustand、Redux)存储需要传递的状态,上一页直接读取全局状态即可:
// 示例:用Zustand实现全局状态 import { create } from 'zustand'; const useBackStateStore = create((set) => ({ backState: null, setBackState: (state) => set({ backState: state }), })); // 回退页面 const goBackWithState = () => { useBackStateStore.getState().setBackState({ animate: false }); navigate(-1); }; // 目标页面 const TargetPage = () => { const backState = useBackStateStore((state) => state.backState); return <div>{backState?.animate ? '执行动画' : '不执行动画'}</div>; };
方案2:临时存储到SessionStorage
将状态存入sessionStorage,回退后在上一页读取并清理:
// 回退页面 const goBackWithState = () => { sessionStorage.setItem('backState', JSON.stringify({ animate: false })); navigate(-1); }; // 目标页面 import { useEffect, useState } from 'react'; import { useLocation } from 'react-router-dom'; const TargetPage = () => { const [backState, setBackState] = useState(null); const location = useLocation(); useEffect(() => { const storedState = sessionStorage.getItem('backState'); if (storedState) { setBackState(JSON.parse(storedState)); sessionStorage.removeItem('backState'); } }, [location]); return <div>{backState?.animate ? '执行动画' : '不执行动画'}</div>; };
内容的提问来源于stack exchange,提问作者Madhan S
相关产品推荐
相关产品推荐

