React Router路由详解

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;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/401357.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TLS 1.2详解

TSL由多个协议组成的两层协议集合&#xff0c;工作与应用层和传输层之间。 TLS协议包含两层协议&#xff1a;记录层协议&#xff08;TLS Record Protocol协议&#xff09;和 握手协议&#xff08;TLS Handshake Protocol协议&#xff09;&#xff0c;底层采用可靠传输协议&…

个人作业2——英语学习APP案例分析

第一部分 调研&#xff0c; 评测 1.下载并使用&#xff0c;描述最简单直观的个人第一次上手体验&#xff1a; 没有各种广告&#xff0c;界面简洁&#xff0c;软件安装包略小于其他翻译软件。就内存的占用而言优于同款热门软件有道词典。 2.必应词典&#xff08;Android客户端&a…

IOS开发UI篇之──自定义加载等待框(MBProgressHUD)

这里介绍一下网友开源的MBProgressHUD类&#xff0c;实现等待框&#xff0c; 一、网上下载 MBProgessHUD 类文件&#xff0c;直接导入到工程即可 二、示例分析 在我的工程中示例如下&#xff1a; 1&#xff09;在ShowImageViewController.h头文件代码如下&#xff1a; #import…

WindowProc和DefWindowProc的区别

1. WindowProc是你给自己的窗口定义的窗口处理函数 DefWindowProc是windows平台提供的默认窗口处理函数 如果某些消息你不需要做特别的处理&#xff0c;调用DefWindowProc进行处理就可以了&#xff0c;不需要你自己再去些那些windows的"标准动作"2. 根据1&#xff0c…

唯一约束(UNIQUE_KEY)

唯一约束可以保证记录的唯一性 唯一约束的字段可以为空值&#xff08;NULL&#xff09; 每张数据表可以存在多个唯一约束&#xff08;主键只有一个&#xff09; mysql> CREATE TABLE tb7( -> id SMALLINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, -> username VARCHAR(2…

HDOJ---2236 无题II[二分枚举+匈牙利]

无题II Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 571 Accepted Submission(s): 296 Problem Description这是一个简单的游戏&#xff0c;在一个n*n的矩阵中&#xff0c;找n个数使得这n个数都在不同的行和…

Oracle 11gR2 RAC恢复OCR和VOTE DISK

Oracle 11gR2 RAC恢复OCR和VOTE DISK原文链接&#xff1a;http://www.askmaclean.com/archives/11-2-lost-ocr-votedisk-group-recovery.html之前有同学在我的Oracle Allstarts群里讨论关于丢失包含ocr和votedisk的ASM diskgroup导致11gR2 RAC cluster无法正常启动的问题&#…

vue3开发实践笔记

一、setup 生命周期 1、执行时机&#xff1a;会在beforeCreate之前执行&#xff0c;内部无法访问this 2、setup 包含的生命周期 onBeforeMount——挂载开始前调用 onMount——挂载后调用 onBeforeUpdate——当响应数据改变&#xff0c;且重新渲染前调用 onUpdated——重新渲…

GetLastError()函数返回值及含义

GetLastError返回的值通过在api函数中调用SetLastError或SetLastErrorEx设置。函数并无必要设置上一次错误信息&#xff0c;所以即使一次GetLastError调用返回的是零值&#xff0c;也不能担保函数已成功执行。只有在函数调用返回一个错误结果时&#xff0c;这个函数指出的错误结…

LINQ系列:Linq to Object排序操作符

LINQ排序操作符包括&#xff1a;OrderBy、OrderByDescending、ThenBy、ThenByDescending及Reverse。 1. OrderBy 1>. 原型定义 public static IOrderedQueryable<TSource> OrderBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func&l…

第5章 为手机而设计

5&#xff0e;为手机而设计 至此,你已经了解了手机&#xff0c;通过一个简单的应用程序的演练了工作方式并且学习XAML的基础知识。现在你应该开始考虑你要编写的应用程序的性质。虽然很容易想到的是手机只是Silverlight存在于另一个屏幕上而已&#xff0c;但是事实没有这么简单…

vue3.x全局toast、message、loading组件

vue3.x全局toast、message、loading组件Toast组件loadingToast组件 在 src/components下创建toast文件夹&#xff0c;并依此创建index.vue和index.js 1、index.vue 一般toast会有如下功能&#xff1a;背景色、字体颜色、文本、停留时间 <template> <div class"…

知天命

吾乃浑浑噩噩、后知后觉之人。 今欲窥天命之道。天命&#xff0c;何也&#xff1f; 天之命乎&#xff0c;或人之道乎&#xff1f; 人生于此世。 盲从于世上&#xff0c;依其欲而行&#xff0c;乃天之命也。 人可存之世上仅百载&#xff0c;终白土亦。 随意欲而为&#xff0c;应…

教程:在 VM Depot 中查找 Azure 可用的虚拟机镜像

&#xfeff;&#xfeff;发布于 2014-07-08 作者 陈 忠岳 对于 Azure 的社区管理虚拟机资源库——VM Depot——的用户来说&#xff0c;网站的搜索功能已得到极大的改善。这一搜索能力的增强&#xff0c;可以帮助用户更容易地找到 Azure 可用的开源 Linux 虚拟机。 搜索发现 …

HDU 1203 I NEED A OFFER!(01背包)

I NEED A OFFER! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 9932 Accepted Submission(s): 3687 Problem DescriptionSpeakless很早就想出国&#xff0c;现在他已经考完了所有需要的考试&#xff0c;准备了…

H5实现微信摇一摇功能

//摇一摇<script type"text/javascript"> var num 1; var SHAKE_THRESHOLD 2000; var last_update 0; var x y z last_x last_y last_z 0; function init() { if (window.DeviceMotionEvent) { window.addEventListener(devicemotion, deviceMotionHan…

PHP起点 - 运算符

一.算术运算符 名称    操作符    举例 加法          $a $b 减法     -      $a - $b 乘法     *     $a * $b 除法运算   /      $a / $b 取余运算   %     $a % $b 递增运算        $a, $a 递减运算  …

Java I/O流

字符流&#xff1a; Reader&#xff1a;用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。 |---BufferedReader&#xff1a;从字符输入流中读取文本&#xff0c;缓冲各个字符&#xff0c;从而实现字符、数组和行的高效读取。 可以指定缓冲区…

java中跨时区的日期格式转换

2019独角兽企业重金招聘Python工程师标准>>> 先上一段代码 public class DataTransfer {public static void main(String[] args) {String dateStr "Sep 30, 2014 12:00:00 AM";SimpleDateFormat sdf new SimpleDateFormat();sdf.applyPattern("MM…

Asp.net WebForm中应用Jquery EasyUI Layout

Asp.net WebForm中应用Jquery EasyUI Layout 按照EasyUI文档中的示例&#xff0c;编写layout代码&#xff1a; <body class”easyui-layout”> <div region"north" border"false" style"height:60px;background:#B3DFDA;">north reg…