如何通过React Router获取上一位置?监听LOCATION_CHANGE无响应
解决React Router无法监听
@@router/LOCATION_CHANGE获取上一位置的问题 看起来你遇到的是React Router版本升级后,原来依赖的@@router/LOCATION_CHANGE action不再触发的问题对吧?大概率是你升级到了React Router v6——从这个版本开始,官方彻底移除了和Redux的默认集成,不会自动派发这个action了。下面给你几个实用的解决方案:
方案一:用React Router自带钩子实现(推荐,最符合v6设计)
不用折腾Redux,直接用useLocation和useEffect就能轻松跟踪上一位置:
import { useLocation, useEffect, useState } from 'react-router-dom'; // 封装成自定义钩子,方便全局复用 function usePreviousLocation() { const location = useLocation(); const [previousLocation, setPreviousLocation] = useState(null); useEffect(() => { // 用location.key判断是否是新路由(避免同路由参数变化重复触发) if (location.key !== previousLocation?.key) { setPreviousLocation(prev => location); } }, [location]); return previousLocation; } // 在组件里用的示例 function MyPage() { const currentLocation = useLocation(); const previousLocation = usePreviousLocation(); console.log('上一页路径:', previousLocation?.pathname); console.log('当前路径:', currentLocation.pathname); return <div>页面内容</div>; }
这种方式代码简洁,完全贴合React Router v6的用法,不需要额外配置Redux。
方案二:手动给Redux派发路由变化action(如果必须用Redux管理)
要是你项目里必须把路由状态存在Redux里,可以自己监听路由变化,手动派发action:
- 先定义action类型和创建函数:
// src/actions/routerActions.js export const LOCATION_CHANGE = 'LOCATION_CHANGE'; export const updateLocationHistory = (prevLoc, currLoc) => ({ type: LOCATION_CHANGE, payload: { previousLocation: prevLoc, currentLocation: currLoc } });
- 修正你的reducer(顺便帮你改了之前的大小写bug:
newstate和newState不一致):
// src/reducers/routerLocations.js import { LOCATION_CHANGE } from '../actions/routerActions'; const initialState = { previousLocation: null, currentLocation: null }; const routerLocations = (state = initialState, action) => { switch (action.type) { case LOCATION_CHANGE: return { ...state, previousLocation: action.payload.previousLocation, currentLocation: action.payload.currentLocation }; default: return state; } }; export default routerLocations;
- 在根组件里监听路由变化并派发action:
import { useLocation, useEffect, useState } from 'react-router-dom'; import { useDispatch } from 'react-redux'; import { updateLocationHistory } from './actions/routerActions'; function App() { const location = useLocation(); const dispatch = useDispatch(); const [prevLocation, setPrevLocation] = useState(null); useEffect(() => { // 第一次加载时没有上一位置,跳过派发 if (prevLocation) { dispatch(updateLocationHistory(prevLocation, location)); } setPrevLocation(location); }, [location, dispatch, prevLocation]); return ( <div className="app-container"> {/* 你的路由组件 */} </div> ); }
这样Redux里就能始终拿到最新的上一位置和当前位置了。
小提醒
另外看你原来的reducer代码,有个小bug:你声明了const newstate = { ...state };,但后面用了newState(大小写不一样),就算之前的action能触发,状态也更新不了,这个要注意哦~
内容的提问来源于stack exchange,提问作者GooseZA
相关产品推荐
相关产品推荐

