问题描述:
今天在项目使用React Router遇到了一个很奇怪的现象,代码大概是这样的:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import {Router, Route, Switch, Redirect, Link} from "react-router-dom";
import history from "./app/history";
import Monitor from "./monitor";
import State from "./state";
ReactDOM.render(
<React.StrictMode>
<Router history={history}>
<main>
<div/>
<ul role="nav">
<li><Link to="/state">State</Link></li>
<li><Link to="/monitor">Monitor</Link></li>
</ul>
<Switch>
<Redirect exact from="/" to="/state"/>
<Route path={"/state"} component={State}/>
<Route path={"/monitor"} component={Monitor}/>
<Redirect to={"/404"}/>
</Switch>
</main>
</Router>
</React.StrictMode>,
document.getElementById('root')
);
正常情况下点击/state会调到State组件,点/monitor会调到Monitor组件,但是,真实情况是这样的:
- 浏览器输入
localhost:3000/state
或localhost:3000/monitor
,会正常跳转
但是当点击/monitor link时,会先跳转到/404,然后再点一次link,又会跳回/monitor,但是此时是没有任何东西返回到页面的,效果见下面的gif。
原因分析:
检查各个组件的state,发现location这个对象变形了,如下面两张图,第一张图是刷新页面后的location对象,里面的pathname是正常的,第二张图是点完link之后的location对象,location里面又产生了一个location对象,而Route使用location.pathname的匹配来渲染组件,但是此时已经渲染不到了,所以会跳转到404,再次点击的时候依然只是更改了url,没有组件可以渲染
解决方案:
找到一个方法可以解决这个location.location的问题,把上面import Router更改为import BrowserRouter,即可。