react-router从v5升级到v6之后做了非常大的改动(刚学习的时候非常头疼):
具体的新特性可以看这篇文章:https://blog.csdn.net/weixin_40906515/article/details/104957712
也可以看react-router的官方网站的迁移策略:https://reactrouter.com/docs/en/v6/upgrading/v5
在react-router v6的文档以及很多网上的博客中,在组件中使用路由参数location
、history
、match
的时候,介绍的只有在函数组件中使用hooks的形式(官方推荐),经过尝试,确实可以实现。但是在类组件中如何使用根本没有提到,我做了一个实验发现根本获取不到,如下图:
这是一个类组件,并且,这个组件是通过路由进入访问的,不是普通组件:
在运行控制台打印的是:
发现props是一个空对象!!! 这样很多的功能根本通过路由参数实现不了了,比如:
- 编程式路由导航,在非受控组件中可以使用
useNavigate
这个钩子进行导航,而在类组件中无能为力,只能想办法使用<Navigate>
这个标签,非常的麻烦,可以看看这篇文章:https://www.jianshu.com/p/5bdfd2fac2cd - 获取路由参数 ,在以往的
react-router-dom
版本中,路由的三个参数location
、history
、match
都是直接挂载到组件的props
身上,即使组件不是路由组件,也可以使用withRouter
高阶组件对普通组件进行增强,也可以将这三个参数带到props
身上。在v6版本中withRouter
直接被移除。怎么办?
估计官方的目的是极力推荐我们使用React Hooks ,从而提高类组件的使用门槛(tm不能像vue那样做做兼容,平滑过度吗?)。只能自己编写高阶组件withRouter
从而实现这一需求,可以看看这篇文章中的回答:https://cloud.tencent.com/developer/ask/sof/296970
export function withRouter( Child ) {
return ( props ) => {
const location = useLocation();
const navigate = useNavigate();
return <Child { ...props } navigate={ navigate } location={ location } />;
}
}
import React from "react";
import { NavigateFunction, useLocation, useNavigate, useParams } from "react-router";
export interface RoutedProps<Params = any, State = any> {
location: State;
navigate: NavigateFunction;
params: Params;
}
export function withRouter<P extends RoutedProps>( Child: React.ComponentClass<P> ) {
return ( props: Omit<P, keyof RoutedProps> ) => {
const location = useLocation();
const navigate = useNavigate();
const params = useParams();
return <Child { ...props as P } navigate={ navigate } location={ location } params={ params }/>;
}
}
在使用的时候:
import { withRouter, RoutedProps } from '../../utils/withRouter';
class ArticleList extends Component<RoutedProps> {
state = {
articleList: [],
curPage: 1,
loginToken: getToken(),
loginUser: getLoginUser()
}
componentWillMount() {
console.log(this)
}
render() {
return (
<div>
...
</div>
)
}
}
export default withRouter(ArticleList);
在控制台输出