react-router-dom初探

react-router是路由组件核心,而react-router-dom是在react-router的基础上扩展了dom组件Link、HashRouter等。

1.react-router-dom安装

npm install react-router-dom --save

2.基础使用方法

直接贴代码,首先需要从reacr-router-dom中引出所需的组件,这里采用hash模式路由,此次我再router.js文件中配置了路由规则,包括path和component,之后循环出路由组件。其中switch组件用于选择其下的匹配路由进行展示,其中还包含Redirect重定向组件,当所有的路由都无法匹配时,会重定向到该组件配置的to路由。

// App.jsx
import React, {
  Component
} from 'react';
import router from './router/index';
import { HashRouter, Route, Switch, Redirect  } from 'react-router-dom';

class App extends Component {
  constructor(props) {
    super(props);
  }
  initRouter () {
    let routerList = router.map(item => (
      <Route
          component={item.component}
          exact
          key={item.path}
          path={item.path}
      ></Route>
    ));
    return routerList;
  }
  render () {
    return (
      <div className="App">
        <HashRouter>
          <Switch>
            {this.initRouter.bind(this)()}
            <Redirect
                path="/*"
                to="/home"
            ></Redirect>
          </Switch>
        </HashRouter>
      </div >
    );
  }
}

export default App;

以下为路由配置文件,其中引入了@loadable/component包用于路由懒加载,优化首页加载速度

// router.js路由配置
// 路由懒加载方式
import loadable from '@loadable/component'

const router = [{
    path: '/home',
    component: loadable(() => import('../pages/HomePage'))
  },
  {
    path: '/detail',
    component: loadable(() => import('../pages/DetailPage'))
  }
];

export default router;

3.路由跳转

方法一:使用react-router-dom提供的Link组件进行跳转

<Link to="/about">About</Link>

方法二:使用react-router-dom封装的push、goBack、go、replace方法进行跳转

// 可以使用对象也可使用路径path
this.props.history.push({
  pathname: '/detail'
});
this.props.history.push( '/detail');
// 类似vue的go
this.props.history.go(-1);
// 返回上一路由
this.props.history.goBack();
// 替换当前路由防止出现死循环
this.props.history.replace('/detail');

4.路由传参

方法一:params,利用此方法传递的参数会保留在浏览器的地址栏,刷新页面参数与任然存在,从match中取值,建议采用这种方法。
<Route path='/path/:name/:id' component={Demo}/>
<link to="/path/lisi/2">xxx</Link>
this.props.history.push({pathname:"/path/" + name + id});
读取参数用:this.props.match.params // { name: 'lisi', id:'2' }
方法二:query,此方法传递的参数不会存在于地址栏,故刷新页面参数会丢失,从location中取值。
<Route path='/query' component={Demo}/>
<Link to={{ path : ' /query' , query : { name : 'lisi' }}}>
this.props.history.push({pathname:"/query",query: { name : 'lisi' }});
读取参数用: this.props.location.query   // { name:'lisi' }
方法三:state,此方法和query方法相似,同样是隐式传递,从location中取值,不会存在于地址栏,刷新页面参数会丢失,但是state中的数据是加密传输的,较安全。
<Route path='/sort ' component={Demo}/>
<Link to={{ path : ' /sort ' , state : { name : 'lisi' }}}> 
this.props.history.push({pathname:"/sort ",state : { name : 'lisi' }});
读取参数用: this.props.location.query  // { name:'lisi' }

5.使用react.lazy实现路由懒加载

前面我们利用的是loadable-components插件实现的路由懒加载,在react16.6.0后,react引入了lazy方法,用于动态加载组件,由此我们可以利用它来实现路由懒加载。

// 路由懒加载方式

// 利用loadable/component动态加载组件
// import loadable from '@loadable/component'

// const router = [{
//     path: '/home',
//     component: loadable(() => import('../pages/HomePage'))
//   },
//   {
//     path: '/detail',
//     component: loadable(() => import('../pages/DetailPage'))
//   },
//   {
//     path: '/mobx',
//     component: loadable(() => import('../pages/testmobx'))
//   }
// ];

// 利用react.lazy动态加载组件
import { lazy } from 'react'
const router = [{
  path: '/home',
  component: lazy(() => import('../pages/HomePage'))
},
{
  path: '/detail',
  component: lazy(() => import('../pages/DetailPage'))
},
{
  path: '/mobx',
  component: lazy(() => import('../pages/testmobx'))
}
];

export default router;

组件渲染,需要注意的是使用react.lazy动态加载路由必须指定Suspense,并添加回调渲染组件,用于在加载组件过程中显示loading效果,如果不指定该组件,react会报错

import React, {
  Component,
  Suspense
} from 'react';
import router from './router/index';
import { HashRouter, Route, Switch, Redirect } from 'react-router-dom';

class App extends Component {
  initRouter () {
    let routerList = router.map(item => (
      <Route
        component={item.component}
        exact
        key={item.path}
        path={item.path}
      ></Route>
    ));
    return routerList;
  }
  render () {
    return (
      <div className="App">
        <HashRouter>
          <Suspense fallback={<div>Loading...</div>}>
            <Switch>
              {this.initRouter.bind(this)()}
              <Redirect
                path="/*"
                to="/home"
              ></Redirect>
            </Switch>
          </Suspense>
        </HashRouter>
      </div >
    );
  }
}

export default App;

6.使用react-router-config实现嵌套路由

react-router-config是为react-router写的优雅的配置路由表的插件
react-router-config地址

其实上面的路由也是采用路由配置的方式组织的,但是不够优雅,也不支持嵌套路由,使用react-router-config将方便我们进行路由嵌套配置。
1.修改路由配置表如下,其中Home组件下嵌套了TestMobx组件,并接收id参数

注意:嵌套路由的父组件(此处是Home组件)不可以添加 exact: true选项,添加后会导致子路由无法匹配,无法实现嵌套路由

const router = [{
    path: '/home',
    component: lazy(() => import('../pages/HomePage')),
    routes: [{
      path: '/home/mobx/:id',
      component: lazy(() => import('../pages/testmobx'))
    }]
  },
  {
    path: '/detail',
    component: lazy(() => import('../pages/DetailPage')),
    exact: true
  },
];

export default router;

2.修改路由组件利用renderRoutes 函数渲染route组件

import React, {
  Component,
  Suspense
} from 'react';
import router from './router/index';
import { HashRouter, Route, Switch, Redirect,Link } from 'react-router-dom';
import { renderRoutes } from "react-router-config";
class App extends Component {
  initRouter () {
    let routerList = router.map(item => (
      <Route
        component={item.component}
        exact
        key={item.path}
        path={item.path}
      ></Route>
    ));
    return routerList;
  }
  render () {
    return (
      <div className="App">
        <HashRouter>
          <ul>
            <li><Link to="/home">首页</Link></li>
            <li><Link to="/detail">详情页</Link></li>
            <li><Link to="/home/mobx/123">嵌套</Link></li>
          </ul>
          <Suspense fallback={<div>Loading...</div>}>
            <Switch>
              {renderRoutes(router)}
              <Redirect
                path="/*"
                to="/home"
              ></Redirect>
            </Switch>
          </Suspense>
        </HashRouter>
      </div >
    );
  }
}

export default App;

3.想要实现嵌套,必不可少的我们需要在父级组件出添加renderRoutes渲染this.props.route.routes其中的子组件。

import React, { Component } from 'react';
import { Button } from 'antd';
import { renderRoutes } from "react-router-config";

class HomePage extends Component {
  render () {
    return (
      <div>
        <div >homePage</div>
        {/* 此处的routes应该是配置中的子组件,如果路由配置中配置的children,那么这里就是 this.props.route.children*/}
        {renderRoutes(this.props.route.routes, { someProp: "these extra props are optional" })}
      </div>
    );
  }
}

export default HomePage;

7.router-react-dom相关链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,616评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,020评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,078评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,040评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,154评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,265评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,298评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,072评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,491评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,795评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,970评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,654评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,272评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,985评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,815评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,852评论 2 351

推荐阅读更多精彩内容