React Router路由详解

  • 一、基础
    • 1、安装使用
    • 2、React Router 中通用的组件
    • 路由组件 BrowserRouter 和 HashRouter
    • 路径匹配组件: Route 和 Switch
    • 导航组件: Link 和 NavLink
    • Redirect 重定向
    • withRouter
    • 编程式导航 - history 对象
    • 路由过渡动画
    • 打包部署的路由配置
    • 3、路由配置实例

一、基础

1、安装使用

React Router 是一个基于 React 之上的强大路由库,它可以让你向应用中快速地添加视图和数据流,同时保持页面与 URL 间的同步。

安装

npm install react-router-dom

实例

import React, { Component, Fragment } from 'react';
import { Provider } from 'react-redux';
import { BrowserRouter, Route } from 'react-router-dom';
import store from './store';import Header from './common/header';
import Home from './pages/home';
import Detail from './pages/detail';
import Login from './pages/login';class App extends Component {render() {return (<Provider store={store}><Fragment><BrowserRouter><div><Header /><Route path='/' exact component={Home}></Route><Route path='/login' exact component={Login}></Route><Route path='/detail/:id' exact component={Detail}></Route></div></BrowserRouter></Fragment></Provider>)}
}export default App;

2、React Router 中通用的组件

有三种:

  • 路由组件(作为根组件):BrowserRouterhistory模式) 和 HashRouterhash模式)
  • 路径匹配组件:RouteSwitch
  • 导航组件:LinkNavLink

路由组件 BrowserRouter 和 HashRouter

BrowserRouterhistory模式) 和 HashRouterhash模式)作为路由配置的最外层容器,是两种不同的模式,可根据需要选择。

关于路由组件,如果我们的应用有服务器响应web的请求,建议使用<BrowserRouter>组件; 如果使用静态文件服务器,建议使用<HashRouter>组件

history 模式:

class App extends Component {render() {return (<BrowserRouter><Header /><Route path='/' exact component={Home}></Route><Route path='/login' exact component={Login}></Route><Route path='/detail/:id' exact component={Detail}></Route></BrowserRouter>)}
}

hash 模式:

class App extends Component {render() {return (<HashRouter><Header /><Route path='/' exact component={Home}></Route><Route path='/login' exact component={Login}></Route><Route path='/detail/:id' exact component={Detail}></Route></HashRouter>)}
}

路径匹配组件: Route 和 Switch

【Route】用来控制路径对应显示的组件

Route 参数:

  • path 指定路由跳转路径
  • exact 精确匹配路由
  • component 路由对应的组件
import About from './pages/container/about';
<Route path='/about' exact component={About}></Route>
  • render 通过写render函数返回具体的dom
<Route path='/about' exact render={() => (<div>about</div>)}></Route>// 或者直接返回 About 组件
<Route path='/about' exact render={() => <About /> }></Route>// 这样写的好处是,不仅可以通过 render 方法传递 props 属性,并且可以传递自定义属性
<Route path='/about' exact render={(props) => {return <About {...props} name={'cedric'} />
}}></Route>// render 方法也可用来进行权限认证
<Route path='/user' exact render={(props) => {// isLogin 从 redux 中拿到, 判断用户是否登录return isLogin ? <User {...props} name={'cedric'} /> : <div>请先登录</div>
}}></Route>
  • location 将与当前历史记录位置以外的位置相匹配,则此功能在路由过渡动效中非常有用
  • sensitive 是否区分路由大小写
  • strict 是否配置路由后面的 ‘/’

Switch

【Switch 】 渲染与该地址匹配的第一个子节点 <Route> 或者 <Redirect>
类似于选项卡,只是匹配到第一个路由后,就不再继续匹配

<Switch> <Route path='/home'  component={Home}></Route><Route path='/login'  component={Login}></Route> <Route path='/detail' exact  component={detail}></Route> <Route path='/detail/:id'  component={detailId}></Route> <Redirect to="/home" from='/' />
</Switch>当路由为/detail/1时,只会访问匹配组件detail, 所以需要在detail路由上加上exact

注意:如果路由 Route 外部包裹 Switch 时,路由匹配到对应的组件后,就不会继续渲染其他组件了。但是如果外部不包裹 Switch 时,所有路由组件会先渲染一遍,然后选择到匹配的路由进行显示。

导航组件: Link 和 NavLink

Link 和 NavLink 都可以用来指定路由跳转,NavLink 的可选参数更多。

Link

两种配置方式:

  • 通过字符串执行跳转路由
<Link to='/login'><span>登录</span></Link>
  • 通过对象指定跳转路由
  1. pathname 表示要链接到的路径的字符串
  2. search 表示查询参数的字符串形式
  3. hash 放入网址的 hash,例如 #a-hash
  4. state 状态持续到 location。通常用于隐式传参(埋点),可以用来统计页面来源
<Link to={{pathname: '/login',search: '?name=cedric',hash: '#someHash',state: { fromWechat: true }}}><span>登录</span>
</Link>点击链接 进入 Login 页面后,就可以在this.props.location.state中看到 fromWechat: true

NavLink

可以看做 一个特殊版本的 Link,当它与当前 URL 匹配时,为其渲染元素添加样式属性。

<Link to='/login' activeClassName="selected"><span>登录</span>
</Link><NavLinkto="/login"activeStyle={{fontWeight: 'bold',color: 'red'}}
><span>登录</span>
</NavLink>
  1. exact 如果为 true,则仅在位置完全匹配时才应用 active 的类/样式
  2. strict 当为 true,要考虑位置是否匹配当前的URL时,pathname 尾部的斜线要考虑在内
  3. location 接收一个location对象,当url满足这个对象的条件才会跳转
  4. isActive 接收一个回调函数,只有当 active 状态变化时才能触发,如果返回false则跳转失败
const oddEvent = (match, location) => {if (!match) {return false}const eventID = parseInt(match.params.eventID)return !isNaN(eventID) && eventID % 2 === 1
}<NavLinkto="/login"isActive={oddEvent}>login</NavLink>

Redirect 重定向

<Redirect> 将导航到一个新的地址
<Redirect> 常用在用户是否登录

<Switch> <Route path='/home' exact component={Home}></Route><Route path='/login' exact component={Login}></Route> <Redirect to="/home" from='/' exact /> // 当访问路由‘/’时,会直接重定向到‘/home’
</Switch>
class Center extends PureComponent {render() {const { loginStatus } = this.props;if (loginStatus) {return (<div>个人中心</div>)} else {return <Redirect to='/login' />}}
}
// 使用对象形式
<Redirectto={{pathname: "/login",search: "?utm=your+face",state: { referrer: currentLocation }}}
/>

withRouter

withRouter 可以将一个非路由组件包裹为路由组件,使这个非路由组件也能访问到当前路由的match, location, history对象

import { withRouter } from 'react-router-dom';class Detail extends Component {render() {··· ···}
}const mapStateToProps = (state) => {return {··· ···}
}const mapDispatchToProps = (dispatch) => {return {··· ···}
}export default connect(mapStateToProps, mapDispatchToProps)(withRouter(Detail));

编程式导航 - history 对象

history 对象的属性和方法:

  • length - (number) history 堆栈的条目数
    action - (string) 当前的操作(PUSH, REPLACE, POP)
    location - (object) 当前的位置。

location 属性:

  • pathname - (string) URL 路径
  • search - (string) URL 中的查询字符串
  • hash - (string) URL 的哈希片段
  • state - (object) 提供给例如使用 push(path, state) 操作将 location 放入堆栈时的特定 location 状态。只在浏览器和内存历史中可用。
  • push(path, [state]) - (function) 在 history 堆栈添加一个新条目
  • replace(path, [state]) - (function) 替换在 history 堆栈中的当前条目
  • go(n) - (function) 将 history 堆栈中的指针调整 n
  • goBack() - (function) 等同于 go(-1)
  • goForward() - (function) 等同于 go(1)
  • block(prompt) - (function) 阻止跳转。

eg:点击img进入登录页

class Home extends PureComponent {goHome = () => {console.log(this.props);this.props.history.push({pathname: '/login',state: {identityId: 1}})}render() {return (<img className='banner-img' alt='' src="img.png" onClick={this.goHome} />)}
}

只有通过 Route 组件渲染的组件,才能在 this.props 上找到 history 对象。
如果想在路由组件的子组件中使用 history ,需要使用 withRouter 包裹

import React, { PureComponent } from 'react';
import { withRouter } from 'react-router-dom';class 子组件 extends PureComponent {goHome = () => {this.props.history.push('/home')}render() {console.log(this.props)return (<div onClick={this.goHome}>子组件</div>)}
}export default withRouter(子组件);

路由过渡动画

import { TransitionGroup, CSSTransition } from "react-transition-group";<Route render={({location}) => {console.log(location);return (<TransitionGroup><CSSTransitionkey={location.key}classNames='fade'timeout={300}><Switch><Redirect exact from='/' to='/home' /><Route path='/home' exact component={Home}></Route><Route path='/login' exact component={Login}></Route><Route path='/write' exact component={Write}></Route><Route path='/detail/:id' exact component={Detail}></Route><Route render={() => <div>Not Found</div>} /></Switch></CSSTransition></TransitionGroup>)
}}>
</Route>
.fade-enter {opacity: 0;z-index: 1;
}.fade-enter.fade-enter-active {opacity: 1;transition: opacity 300ms ease-in;
}

打包部署的路由配置

如果 react-router 路由 使用了 history 模式(即),那么在 Nginx 配置中必须加上:

location / {··· ···try_files $uri /index.html;··· ···}}

如果 react-router 路由 使用了 hash 模式(即),那么在 Nginx 中不需要上面的配置。

3、路由配置实例

routers/config.js 路由配置文件

import React, { lazy } from 'react';import BasicLayout from '../layouts/BasicLayout/index.jsx';
import BlankLayout from '../layouts/BlankLayout/index.jsx';
import Login from '../pages/Login/index.jsx';
import Welcome from '../pages/Welcome/index.jsx';// 懒加载
const Home = lazy(() =>import(/* webpackChunkName: "Home" */ 'Home/App.jsx')
)
const Mine = lazy(() =>import(/* webpackChunkName: "Mine" */ 'Mine/App.jsx')
)const config = [{path: '/',component: BlankLayout,childRoutes: [{path: '/login', // 路由路径name: '登录页', // 菜单名称 (不设置,则不展示在菜单栏中)component: Login,},{path: '/',component: BasicLayout,childRoutes: [{path: '/welcome',name: '欢迎页',icon: 'logo',component: Welcome,},{path: '/home',name: '首页',component: Home,},{path: '/mine',name: '个人中心',component: Mine,},{ path: '/', exact: true, redirect: '/welcome' },{ path: '*', exact: true, redirect: '/404' },],},],},
];export default config;

main.js 入口文件

import React from 'react';
import ReactDom from 'react-dom';import './styles/main.less';
import AppRouter from './routers/index';ReactDom.render(<AppRouter />, document.getElementById('app'));

routers/index.js 路由渲染文件

import React, { Suspense } from 'react';
import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom';import Loading from '../components/Loading/index.jsx';
import config from './config';const renderRoutes = (routes) => {if (!Array.isArray(routes)) {return null;}return (<Switch>{routes.map((route, index) => {if (route.redirect) {return (<Redirectkey={route.path || index}exact={route.exact}strict={route.strict}from={route.path}to={route.redirect}/>);}return (<Routekey={route.path || index}path={route.path}exact={route.exact}strict={route.strict}render={() => {const renderChildRoutes = renderRoutes(route.childRoutes);if (route.component) {return (<Suspense fallback={<Loading />}><route.component route={route}>{renderChildRoutes}</route.component></Suspense>);}return renderChildRoutes;}}/>);})}</Switch>);
};const AppRouter = () => <Router>{renderRoutes(config)}</Router>;export default AppRouter;

BlankLayout/index.jsx 空白页布局

import React from 'react';const BlankLayout = ({ children }) => <>{children}</>;export default BlankLayout;

BasicLayout/index.jsx 基本布局

import React from 'react';
import SiderMenu from '../SiderMenu/index.jsx';
import MainHeader from '../MainHeader/index.jsx';
import MainFooter from "../MainFooter/index.jsx";
import styles from './style.less';const BasicLayout = ({ route, children }) => (<div className={styles.container}><MainHeader /><div>{/* 左侧菜单导航 */}<SiderMenu routes={route.childRoutes} />{/* 右侧菜单内容 */}<div className={styles.contant}>{children}</div></div><MainFooter /></div>
);export default BasicLayout;

Welcome/index.jsx contant内容

import React from 'react';import './index.less';const WelcomePage = () => <div className="welcome">welcome</div>;export default WelcomePage;

React Router路由详解相关推荐

  1. 【React】路由详解

    文章目录 Router 介绍 Router 原理 Router 安装 Router 使用 Link 和 NavLink Route 属性 path 属性 exact 属性 Route 组件 compo ...

  2. angular4和php,Angular4的router使用详解

    这次给大家带来Angular4的router使用详解,Angular4的router使用注意事项有哪些,下面就是实战案例,一起来看一下. router,也就是路由,是前端中一个比较重要的概念.通过ro ...

  3. vue路由详解 --基础

    vue路由详解 --基础 1.router-link 和router-view组件 router-link相当于封装了一个a标签 router-view为组件显示的位置 <router-link ...

  4. angular路由详解

    angular路由 路由 (route) ,几乎所有的 MVC(VM) 框架都应该具有的特性,因为它是前端构建单页面应用 (SPA) 必不可少的组成部分. 那么,对于 angular 而言,它自然也有 ...

  5. API 网关服务:Spring Cloud Zuul(二):路由详解、Cookie 与头信息

    实践出于<Spring Cloud 微服务实战> - 瞿永超 著 路由详解 传统路由配置   传统路由配置就是在不依赖于服务发现机制的情况下,通过在配置文件中具体指定每个路由表达式与服务实 ...

  6. Ocelot简易教程(三)之主要特性及路由详解

    作者:依乐祝 原文地址:https://www.cnblogs.com/yilezhu/p/9664977.html 上篇<Ocelot简易教程(二)之快速开始2>教大家如何快速跑起来一个 ...

  7. react更改路由入参_JavaScript基础教程 react router路由传参

    本篇教程介绍了JavaScript基础教程 react router路由传参,希望阅读本篇文章以后大家有所收获,帮助大家对JavaScript的理解更加深入. < 今天,我们要讨论的是react ...

  8. elasticsearch系列三:索引详解(分词器、文档管理、路由详解(集群))

    目录 一.分词器​ 1. 认识分词器 1.1 Analyzer 分析器 1.2 如何测试分词器 2. 内建的字符过滤器(character filter) 2.1 HTML过滤字符过滤器(HTML S ...

  9. 静态路由和默认路由详解及配置方法️

    目录 一.路由详解 1.路由器工作原理: 2.路由表形成: 3.直连路由: 4.非直连路由: 二.静态路由 1.静态路由详解: 2.配置静态路由 三. 默认路由: 1.默认路由详解 2.配置默认路由方 ...

最新文章

  1. Mysql笔记2-----重要小点
  2. EIGRP-2(EIGRP的路由认证)
  3. 做弱电机房工程的时候,如何解决机房称重问题?
  4. resin php mysql_RedhatAS4.0上安装Apache2+PHP5+MySQL+Resin+SSL+GD+webalizer
  5. python内点法_Python_Day_02 str内部方法总结
  6. js手机号中间四位_11位手机号码隐藏中间四位数,学会Substitute函数一键搞定!...
  7. mfc 子窗体 按钮不触发_VBA与Excel入门——用户窗体1
  8. bootstrap轮播图 原点变为方块_JS实现无缝切换轮播图(自动+手动)
  9. 机器视觉笔记:RANSAC算法以及思想
  10. C语言学习(十)C语言中的小数
  11. SDN入门:Ubuntu下SDN环境搭建(Floodlight+Minite)(踩坑教程,解决FL1.2版本无法访问网页问题)
  12. Swift5 字符串(String)操作
  13. AirPods Pro 和 AirPods 3 固件更新,或将提升稳定性,如何操作看这里
  14. 大学计算机学习心得1000字,大学计算机学习心得体会
  15. [译] linux内存管理之RSS和VSZ的区别
  16. sourcetree连接不上gitlab服务器
  17. Linux常用命令大全(史上最全)建议收藏!
  18. 输入圆柱的底面半径和高,求底面积和体积--简单
  19. R| ggseg 绘制统计结果
  20. 每日一书丨地表最强:iOS安全黑宝书中文版来袭

热门文章

  1. instanceof的用法①
  2. 条款46:需要类型转换的时候请为模板定义非成员函数
  3. 关东升的iOS实战系列图书 《iOS实战:传感器卷(Swift版)》已经上市
  4. Python匿名函数——lambda表达式
  5. Nginx 实战(一) 集群环境搭建
  6. 各个行业纷纷瞅准了这块大蛋糕
  7. ubuntu下查看进程端口
  8. 决策树信息熵计算_决策树熵|熵计算
  9. leetcode 341. 扁平化嵌套列表迭代器(dfs)
  10. leetcode 85. 最大矩形(dp)