react系列-react-router

官方网站:https://reactrouter.com/

基础

路由

路由的含义:网络工程的术语。路由(routing)就是通过互联的网络把信息从源地址传输到目的地址的活动。

路由器提供了两种机制:路由和转送。

  • 路由是决定数据包从来源到目的地的路径
  • 转送将输入端的数据转移到合适的输出端

路由中的概念:

  • 路由表:本质是一个映射表,决定了数据包的指向。

前端路由的原理

前端路由的核心
  • 改变URL,但是页面不要进行强制刷新(a标签会造成强制刷新,所以需要阻止默认行为)
  • 监听URL的改变,并且改变之后自己改变页面的内容

URL发生变化,同时不引起页面的刷新有两个办法:

  • 通过 URL 的 hash 改变 URL,如 localhost:3000/#/abc
  • 通过 HTML5 中的 history 模式修改 URL

具体可以参考链接:修改路径URL不刷新页面

版本

react-router-dom:针对浏览器

react-router-native:针对原生应用

API & 高阶组件

  • BrowerRouter :使用 history 模式对路径改变的处理

  • HashRouter :使用 hash 模式对路径改变的处理

  • Link :通常路径的跳转使用的,最终会被渲染成 a 标签,to 属性用于设置跳转到的路径

  • NavLink :在 Link 基础之上增加了一些样式属性,默认进行模糊匹配

  • Route :用于路径的匹配,匹配的组件占位

  • Switch :只渲染唯一匹配到的路由(排他操作),如果能够匹配到较为精确的路由就不显示通配路由配置

  • Redirect :路由重定向。会执行跳转到对应的 to 路径中

  • history :手动进行跳转时,需要获取 history 对象。

    获取到 history 对象的方式:

    • 如果该组件是通过路由直接跳转过来的,那么可以直接从 props 中获取到 history、location、match对象,路径跳转到目标组件时;
    • 如果该组件是一个普通渲染的组件,那么不可以直接获取 history、location、match对象
  • withRouter :高阶组件。将 history、location、match对象包裹传入到普通组件中。可以让普通组件使用history、location、match对象。必须包裹在 Router 组件中

参数传递

方式:

  • 动态路由,to='/detaitl/:id' 的形式传参,使用 props.match.params.id 获取传参
  • search传递参数,to='detail?id=123' 的形式传参,使用 props.location.search 获取传参,需要进行解析传参
  • Link 中 to 传入对象,对象中的 state 属性可以传递对象数据,使用 props.location.state 获取传参。数据比较复杂的情况下使用

配置

类似于 vue-router 的方式使用配置的方式进行创建 router

需要安装额外的依赖包 react-router-config

使用 renderRoutes(routes) 方式进行渲染。

示例

基础示例

import React, { PureComponent } from 'react'
import {
    BrowserRouter,
    NavLink,
    Link,
    Route,
    Switch
} from 'react-router-dom'

class Home extends PureComponent {
    render() {
        return (
            <h4>Home</h4>
        )
    }
}

class About extends PureComponent {
    render() {
        return (
            <h4>About</h4>
        )
    }
}

export default function useRouter() {
    return (
        <BrowserRouter>
            {/* <Link to='/'>首页</Link>
            <Link to='/about'>关于</Link> */}
            <NavLink exact to='/' activeStyle={{color: 'red'}}>首页</NavLink>
            <NavLink to='/about' activeStyle={{color: 'red'}}>关于</NavLink>

            <Switch>
                 {/* 路径匹配通常是模糊匹配 只有根路径时需要设置精确匹配 */}
                <Route exact path='/'>
                    <Home></Home>
                </Route>

                <Route path='/about' component={About}></Route>
            </Switch>
        </BrowserRouter>
    )
}

路由嵌套

import React, { PureComponent } from 'react'
import {
    BrowserRouter,
    NavLink,
    Link,
    Route,
    Switch
} from 'react-router-dom'

class Home extends PureComponent {
    render() {
        return (
            <h4>Home</h4>
        )
    }
}

class About extends PureComponent {
    render() {
        return (
            <div>
                <NavLink exact to='/about' activeStyle={{color: 'green'}}>关于我们</NavLink>
                <NavLink to='/about/history' activeStyle={{color: 'green'}}>历史</NavLink>
                <NavLink to='/about/culture' activeStyle={{color: 'green'}}>文化</NavLink>
                
                <Switch>
                    <Route exact path='/about'>
                        <h4>About</h4>
                    </Route>
                    <Route path='/about/history'>
                        <h4>历史</h4>
                    </Route>
                    <Route path='/about/culture'>
                        <h4>文化</h4>
                    </Route>
                </Switch>
            </div>
        )
    }
}

export default function useRouter() {
    return (
        <BrowserRouter>
            {/* <Link to='/'>首页</Link>
            <Link to='/about'>关于</Link> */}
            <NavLink exact to='/' activeStyle={{color: 'red'}}>首页</NavLink>
            <NavLink to='/about' activeStyle={{color: 'red'}}>关于</NavLink>

            <Switch>
                 {/* 路径匹配通常是模糊匹配 只有根路径时需要设置精确匹配 */}
                <Route exact path='/'>
                    <Home></Home>
                </Route>

                <Route path='/about' component={About}></Route>
            </Switch>
        </BrowserRouter>
    )
}