React-router使用教程

react-router 通过管理 URL,实现组件的切换和状态变化。

基本用法

React Router 的安装命令:

npm install --save react-router
// 或者
yarn add react-router

使用方式:

import React from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

function Index() {
  return 

Home

; } function About() { return

About

; } function Users() { return

Users

; } function AppRouter() { return (
); } export default AppRouter;

上述示例中:

  • Router组件本身只是一个容器,真正的路由需要通过Route组件定义
  • Route组件中,path属性是指跳转的url,component属性用来定义跳转到的页面组件

注意:path只需要配置 URL 中的路径就行,不需要理会请求参数部分。

如,你的路由配置如下:


那么以下 URL 均匹配到这个路由配置,显示ListPage

  • /list
  • /list?searchText=react
  • /list?searchText=react&beginTime=20180101&endTime=20190530

嵌套路由

import React from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

// App组件中定义根路由
function App() {
  return (
    
      
); } function Home() { return

Home

; } function About() { return

About

; } function Topic({ match }) { return

Requested Param: {match.params.id}

; } // 在Topics组件中定义子路由 function Topics({ match }) { return (

Topics

  • Components
  • Props v. State

Please select a topic.

} />
); } function Header() { return (
  • Home
  • About
  • Topics
); } export default App;

上述示例是在 Topics 组件中嵌套了子路由:

  • Topics组件中,传入一个match对象属性,然后我们继续在 Topics 组件定义 Link 在路径to={${match.url}/components}其中match.url返回的就是/topics,这个跳转路径实际为/topics/components
  • 在 Topics 组件中定义${match.path}/:id} component={Topic} />,这里的 id 对应 ${match.url}/components}>Components中的components
  • 其中${match.path}/:id} component={Topic} />就是的子路由。

Route 组件

Route是用于声明路由映射到应用程序的组件层。Route有两个特别重要的属性:pathcomponent,其中path指定路由匹配的路径(url);component定义路由对应的页面组件。

import { Route } from 'react-router-dom';

const About = () => 
About
; // 当路径匹配到`/about`时,会渲染About组件 ;

其它属性

  • exact

    完全匹配,路径必须完全一致,才能渲染对应页面

     // 路径必须为`/about`时才能渲染About,如果为`/about/:id`则不渲染
    
  • strict

    严格匹配。如果为true,则具有尾部斜杠的路径将仅匹配具有尾部斜杠的location.pathname。当location.pathname中有其他 URL 段时,这不起作用。

  • sensitive

    是否需要区分大小写,如果为 true,则在匹配路径时会区分大小写。

     // 路径必须为`/about`时才能渲染About,如果为`/About`则不渲染
    

Switch

Switch组件将迭代其所有子元素,并且仅渲染与当前位置匹配的第一个子元素,避免重复渲染。


  
  • ContactUs

此时只会渲染一个 ContactUs 组件,而不是重复渲染两次。

Router

Router能够保持 UI 和 URL 的同步。

属性

  • children

    一个或多个Route。当history改变时,Router会匹配出Route的一个分支,并且渲染这个分支中配置的组件,渲染时保持父route组件中嵌套的子route组件。

  • history

    Router监听的history对象

页面跳转

这里我们简单介绍两种页面跳转方式:LinkpushgoBack等方法调用。

Link

允许路由跳转的主要方式。以适当的href去渲染匹配到的路由组件。可以接收到Router的状态。

About // 点击渲染`/about`匹配到的页面

上述示例,当我们点击时,URL会更新,组件会被重新渲染。其中,to指定链接到的路径。

to不仅可以是字符串,还可以 location 是对象。

除此之外,Linkreplace属性如果为 true,则单击该链接将替换历史堆栈中的当前条目,而不是添加新条目。

 //此时历史堆栈中的当前条目会被替换

调用方法

history.push()

import React from 'react';
import { withRouter } from 'react-router';

function Button() {
  const { history } = props;
  return ;
}

export default withRouter(Button);

点击Button,页面将会渲染/about路径匹配到的组件

history.goBack()

import React from 'react';
import { withRouter } from 'react-router';

function Button() {
  const { history } = props;
  return ;
}

export default withRouter(Button);

点击按钮,页面将会回退,渲染前一个组件。

附: 重定向(Redirect)

将导航到新位置。新位置将覆盖历史堆栈中的当前位置。即用户访问一个路由,会自动跳转到另一个路由。

import { Route, Redirect } from 'react-router';

 (loggedIn ?  : )}
/>;

上述示例中,如果路由匹配到/时,loggedIntrue时,路由就会重定向至/dashboard


  
  

上述示例,当路由匹配到/old-path时,会被重定向到/new-path,渲染Place组件。

数据传递

页面之间通过路由参数进行数据交互主要有三种方式:

  • 路径参数
  • 请求参数
  • history state

1. 路径参数

用于传递数据的 id。注意不要因为需要传递一些查询条件等临时数据,不要使用路径参数,而是使用下一节介绍的请求参数。


//通过路由传递gwlx和recordId参数



// HelloWorldPage.tsx中参数获取

import { withRouter } from 'react-router';

function HelloWorldPage(props){
    const {gwlxId,recordId} = props.match.params;
    return (<>
        
公文类型为:{gwlxId}
数据ID为:{recordId}
) } export default withRouter(HelloWorldPage);

2. 请求参数

请求参数可以用来传递除数据 id 之外的数据。如查询条件。

首先看一下一个普通的 URL:

/archive/dispatch-list?userId=123&userName=张三

其中/archive/dispatch-list是路径部分,而?userId=123&userName=张三是查询参数,也称之为请求参数。

我们可以通过location.search获取到查询参数。可以使用qs模块解析查询参数。

const searchParams = qs.parse(
  props.location.search ? props.location.search.substr(1) : '',
);

在创建这样的 URL 时,也可以用qs模块格式化请求参数:

const searchParams = { userId: '123', userName: '张三' };
const url = `/archive/dispatch-list?${qs.stringify(searchParams)}`;
// Button.tsx

import { withRouter } from 'react-router';

function Button(props) {
  return (
    
  );
}

export default withRouter(Button);

// HelloWorldPage.tsx中参数获取

import { withRouter } from 'react-router';
import qs from 'qs';

function HelloWorldPage(props) {
  const { userId, userName } = qs.parse(
    props.location.search ? props.location.search.substr(1) : '',
  );
  return (
    <>
      
用户名为:{userName}
用户ID为:{userId}
); } export default withRouter(HelloWorldPage);

3. history state

使用请求参数可以传递很多数据,但是同时也会污染 URL。有时,我们只想向新页面传递一些临时的数据,又不想让用户在浏览器地址栏上看到非常长的 URL,或者不想让用户收藏这个链接,再次打开这个链接时还带着这些临时数据。如果是这样的情况,我们可以使用history state来传递数据。

请注意:如果是给列表页传递查询条件,使用请求参数。

千万注意:刷新页面或者重新打开页面,不会再有之前的history state数据。浏览器的历史回退、前进会保持页面的history state

// Button.tsx

import { withRouter } from "react-router";

function Button(props) {
  return (
    
  );
}

export default withRouter(Button);

// HelloWorldPage.tsx中参数获取

import { withRouter } from "react-router";

function HelloWorldPage(props) {
  const { gwlxId, recordId } = props.location.state || {};
  return (
    <>
      
公文类型为:{gwlxId}
数据ID为:{recordId}
); } export default withRouter(HelloWorldPage);

小结

路径参数和请求参数的方式适合传递少量的数据,history state 适合传递完整的数据对象。

总结

此教程通过描述 react-router 中的基本组件及其简单用法。更多用法请移步至react-router 官网希望我们能够快速掌握路由定义、路由配置、路由跳转、路由传参等相关技能。

参考资料

  • react-router 官网
  • React Router 4 简易入门
  • React Router 中文文档
  • React Router 使用教程

你可能感兴趣的:(React-router使用教程)