react-router-dom v6 的类组件使用路由的参数

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的文档以及很多网上的博客中,在组件中使用路由参数locationhistorymatch的时候,介绍的只有在函数组件中使用hooks的形式(官方推荐),经过尝试,确实可以实现。但是在类组件中如何使用根本没有提到,我做了一个实验发现根本获取不到,如下图:
在这里插入图片描述
这是一个类组件,并且,这个组件是通过路由进入访问的,不是普通组件
在这里插入图片描述
在运行控制台打印的是:
在这里插入图片描述
发现props是一个空对象!!! 这样很多的功能根本通过路由参数实现不了了,比如:

  • 编程式路由导航,在非受控组件中可以使用useNavigate这个钩子进行导航,而在类组件中无能为力,只能想办法使用<Navigate>这个标签,非常的麻烦,可以看看这篇文章:https://www.jianshu.com/p/5bdfd2fac2cd
  • 获取路由参数 ,在以往的react-router-dom版本中,路由的三个参数locationhistorymatch都是直接挂载到组件的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);

在控制台输出
在这里插入图片描述

  • 13
    点赞
  • 27
    收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页
评论 4

打赏作者

狗剩集团

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值