ReactRouter进阶技巧

简介: ReactRouter进阶技巧

在编写react项目中的时候,常常会用到react-router这个插件来满足项目的需求。这个插件用法起来确实别vue路由用法稍微麻烦了一些,但是只有我们配置好,也能在项目中应用得当。
有时候会需要使用编程式导航,比如上方导航栏里面选项,响应按钮事件,进行路由跳转。react 的做法是通过高阶函数,函数体内部向组件的 props 注册一些路由的方法,最后返回一个新的组件。

下面是一个结合 TypeScript 使用 withRouter 的例子:

interface NavigationState {
  routes: Array<{
    path: string;
    name: string;
    key: string;
  }>;
  selectedKey: string;
}

interface NavigationProps {
  name: string;
}

class Navigation extends Component<
  RouteComponentProps & NavigationProps, // 使用「交叉类型」来处理Props的关系
  NavigationState
> {
  state = {
    routes: [],
    selectedKey: "1"
  };

  toggleRoute = (event: ClickParam) => {
    this.props.history.push(path); // route的方法已经被注册到了Props上
  };

  render() {
     // ...
    );
  }
}

export default withRouter(Navigation);

严格匹配: exact 和 strict

exact已经关闭了模糊匹配。那么strict设置为true(默认是false),会有什么区别呢。例如 path 为 /a的时候:

  • 两个 prop 均为true:不匹配/a/,只匹配/a
  • strict 为 false:/a//a均匹配

路由配置化

可以直接使用 react-router-config 组件,实现原理:

import { Route, Switch, SwitchProps, RouteProps } from "react-router-dom";

function renderRoutes(params: {
  routes: RouteProps[];
  switchProps?: SwitchProps;
}) {
  const { switchProps, routes } = params;
  return (
    <Switch {...switchProps}>
      {routes.map((route, index) => (
        <Route
          key={index}
          path={route.path}
          component={route.component}
          exact={route.exact || true}
          strict={route.strict || false}
        ></Route>
      ))}
    </Switch>
  );
}

假设我们的路由如下:

import { RouteProps } from "react-router-dom";

const config: RouteProps[] = [
  {
    path: "/",
    component: HomePage
  },
  {
    path: "/user",
    component: UserPage
  }
];

路由变化响应

在 VueJS 技术栈中,vue-router 是提供路由响应的钩子函数,例如:beforeEachafterEach等等。

但是在 React 中,react-router 并不提供相关的钩子函数。那么如果有顶部导航栏,不同页面切换时,高亮不同的标签,那么应该怎么实现响应路由变化呢

首先即使是路由,在 React 中,它也是一个组件对象。因此,如果要更新试图,必须触发组件的 render。而触发组件的关键在于,props 发生改变。

第一步:需要使用withRouter来包装对应的组件,将路由的信息作为 props 注入组件,比如顶部导航栏。

第二步:下面是 React17 前后的简单例子。

React17 之前:

import { withRouter, RouteComponentProps } from "react-router-dom";

class Navigation extends Component<RouteComponentProps, any> {
  state = {
    selectedPath: "/"
  };

  // 在componentWillReceiveProps中接受新的props
  // 决定是否更新state
  componentWillReceiveProps(nextProps: RouteComponentProps) {
    if (nextProps.location.pathname === this.props.location.pathname) {
      this.setState({ selectedPath: nextProps.location.pathname });
    }
  }

  render() {
    // 这里的render渲染,取决于state是否更新
    const { selectedPath } = this.state;
    return <div>导航栏选中信息:{selectedPath}</div>;
  }
}

export default withRouter(Navigation);

在 React17 之后,不推荐使用componentWillReceiveProps等不确定的生命周期。处理的思路是:render 函数返回的视图中,变量的变化依赖 props 属性的值。

import { withRouter, RouteComponentProps } from "react-router-dom";

class Navigation extends Component<RouteComponentProps, any> {
  state = {
    paths: ["/", "/a"]
  };

  render() {
    const { pathname } = this.props.location;
    const { paths } = this.state;

    let selectedPath = "";
    paths.some(path => {
      if (path === pathname) {
        selectedPath = path;
        return true;
      }
      return false;
    });

    return <div>导航栏选中信息:{selectedPath}</div>;
  }
}

export default withRouter(Navigation);
相关文章
|
存储 安全 网络安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
【9月更文挑战第17天】在数字化时代,网络安全和信息安全已成为我们生活中不可或缺的一部分。本文将介绍网络安全漏洞、加密技术以及安全意识等方面的知识,帮助读者更好地了解网络安全的重要性,并提供一些实用的技巧和建议来保护个人信息和数据安全。
107 1
|
C++ Python
Python中的类与对象
Python中的类与对象
121 1
|
JSON 弹性计算 前端开发
函数计算产品使用问题之遇到在自定义运行时部署React项目时遇到样式无法正常加载。一般是什么导致的
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
115 0
|
传感器
BOSHIDA DC电源模块在工业控制器中的重要性
DC电源模块在工业控制器中起着非常重要的作用,它是实现工业控制器运转所必需的组成部分。
BOSHIDA DC电源模块在工业控制器中的重要性
|
开发工具 git
[Git]Git概述与安装(二)
[Git]Git概述与安装(二)
react-router-dom6学习2-第一个路由实例
react-router-dom6学习2-第一个路由实例
187 0
react-router-dom6学习2-第一个路由实例
|
存储 缓存 算法
|
Web App开发 PHP
php runtime 中 headers already sent 问题解决方案
本文旨在梳理 Cannot modify header information - headers already sent by (output started at xx 问题的原因,触发条件以及相应的解法
18929 1
Win7笔记本电脑启用虚拟WIFI共享上网
今天看了一个帖子,win7系统通过笔记本的无线网卡,启用虚拟Wifi功能共享上网,自己尝试了一下,感觉很好用,至少没有无线路由的自己,手机可以上wifi了,更新软件玩微信等等,都方便多了,好了,废话不多说,先介绍下吧。
1549 0