React-router v6 使用自定义history报reading 'pathname' undefined错误
问题根源
React Router v6 对底层Router组件的传参做了不兼容修改,你当前的写法还是v5版本的用法:v5的Router支持直接传入history属性,但v6的Router组件不再识别history属性,要求必须传入location、navigator两个必填属性,你只传入了history,内部读取location.pathname时找不到对应值就会抛出这个错误。
解决步骤
1. 安装history依赖
自定义路由能力需要依赖独立的history包,执行安装:
npm install history # 或者yarn add history
2. 编写自定义history实例
创建utils/history.js文件:
import { createBrowserHistory } from 'history'; const myHistory = createBrowserHistory(); export default myHistory;
3. 修改入口文件Router配置
有两种可选方案,推荐使用第二种更简单:
方案A:手动同步history状态(兼容所有v6版本)
修改index.js代码如下:
import myHistory from './utils/history'; import { Router } from 'react-router'; import { useState, useEffect } from 'react'; const Root = () => { // 同步history的状态到React组件 const [historyState, setHistoryState] = useState({ action: myHistory.action, location: myHistory.location, }); useEffect(() => { // 监听history变化,更新状态触发路由重渲染 return myHistory.listen((update) => { setHistoryState(update); }); }, []); return ( <Provider store={store}> <Router location={historyState.location} navigator={myHistory} navigationType={historyState.action} > <App /> </Router> </Provider> ) } ReactDOM.render(<Root />, document.getElementById('root'));
方案B:使用官方封装的HistoryRouter(v6.4+版本支持)
v6.4及以上版本react-router-dom已经正式导出HistoryRouter组件,不需要手动写状态同步逻辑,直接修改index.js即可:
import myHistory from './utils/history'; import { HistoryRouter } from 'react-router-dom'; ReactDOM.render( <Provider store={store}> <HistoryRouter history={myHistory}> <App /> </HistoryRouter> </Provider>, document.getElementById('root') );
Redux action中跳转路由的用法
直接导入自定义的myHistory实例调用跳转方法即可:
import myHistory from '@/utils/history'; // 示例:登录成功后跳转到个人中心 export const login = (userInfo) => async (dispatch) => { // 调用登录接口等逻辑... myHistory.push('/user-profile'); // 替换路由用 myHistory.replace('/xxx') }
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

