React-router 5.0 利用高阶函数实现路由嵌套(web)

如今 react-router 已经升级到v5.0版本,v4.0版本做了较大的改革,代码中依然使用v3.0版本的写法,于是准备整改为v4.0以上版本,遇到了很多坑,于是做个笔记。

首先,对比一下 v3.0 和 v4.0 版本:

  • v4.0提供了react-router-dom:是基于react-router,加入了在浏览器运行环境下的一些功能,例如:LinkNavLinkBrowserRouterHashRouter组件
  • v4.0提供了react-router-config:一个帮助我们配置静态路由的小助手;可以拆分统一管理路由配置,这里很像Vue的写法
  • v4.0中BrowserRouterHashRouter 取代v3.0中的 <Router history={browserHistory}history={hashHistory} />
  • v4.0 中废弃了 < IndexRoute > ,但可以使用 < Route exact > 来达到同样的效果,新增的 < Switch > 标签,用于互斥路由
  • v4.0版本中路由的本质变成了React组件,也就是自定义标签。所以你可以像使用组件一样是用路由。那么嵌套路由无非就是组件嵌套的写法

代码对比:
index.js

// v3.0
import { Router, Route, hashHistory, IndexRedirect } from 'react-router'

<Router history={hashHistory}>
	<Route path={'/'} components={App}>
		<IndexRedirect to="/Index/Home" />  // 重定向路由
		<Route path={'/Index'} component={Index}>
			<IndexRedirect to="/Index/Home" /> // 子路由重定向
			<Route path={'/Index/Home'} components={Home}/>
			<Route path={'/Index/Classify'} components={Classify}/>
		</Route>
		<Route path={'/Login'} components={Login}/>
		<Route path={'/404'} component={NotFound}/>
	</Route>
</Router> 

// v4.0
import { HashRouter, Route, Switch, Redirect } from 'react-router-dom';

<HashRouter>
	<Switch>
		<App> // 这里使用 <Route path={'/'} exact component={App} /> 会报警告 
			<Route path={'/Index'} component={Index}>
				<Redirect to='/Index/Home' /> // 访问 /Index及下级失效路径会重定向到 /Index/Home
				<Route exact path={'/Index/Home'} components={Home}/>
				<Route path={'/Index/Classify'} components={Classify}/>
			</Route>
			<Route path={'/Login'} components={Login}/>
			<Route path={'/404'} component={NotFound}/>
			<Redirect from='/' to='/Index/Home' /> // 访问根路径重定向到 /Index/Home
		</App>
	</Switch>
</HashRouter>

接下来,我们利用v4.0 版本高阶函数拆分路由统一配置(类似vue写法):

routes.js:

let routes = [
 {
    path: '/Index',
    component: Index,
    exact:true
  },
  {
    path: '/Home',
    component: Home,
    exact:false
  },
  {
    path: '/Login',
    component: Login,
    exact:false
  },
]

export default routes

index.js:

import routes from './router/routes'
import { HashRouter, Route, Switch, Redirect } from "react-router-dom";
import App from "./App";

ReactDOM.render(
  <HashRouter>
  	<App> // 这里使用 <Route path={'/'} exact component={App} /> 会报警告 
      <Switch> // 利用map遍历每一项,这里因为是组件,key要注意
      	{
      		routes.map((route,index) => (
	          <Route
	            key={index}
	            path={route.path}
	            exact={route.exact}
	            component={route.component}
	          />
      		))
      	}
      	<Redirect from='/' to='/Index'></Redirect> // 根路径重定向到 /Index
      </Switch>
    </App>
  </HashRouter>,
  document.getElementById('root')
);

实现简单的路由拆分管理,这里也可以利用react-router-config插件内置方法renderRoutes实现,其源码也是基于如下方式;

接下来,我们解决处理组件嵌套的情况:

routes.js:

let routes = [
  {
    path: '/Index',
    component: Index,
    exact:true
  },
  {
    path: '/Home',
    component:Home,
    children:[
      {
        path:'/Home/ShoppingCart',
        component:ShoppingCart,
        exact:true
      },
      {
        path:'/Home/Classify',
        component:Classify,
        exact:false
      },
    ]
  },
  {
    path: '/Login',
    component: Login,
    exact:false
  },
]

export default routes

index.js:

import routes from './router/routes'
import { HashRouter, Route, Switch, Redirect } from "react-router-dom";
import App from "./App";

ReactDOM.render(
  <HashRouter>
  	<App> // 这里使用 <Route path={'/'} exact component={App} /> 会报警告 
      <Switch> // 利用map遍历每一项,这里因为是组件,key要注意
      	{ // 利用render 渲染子路由
      		routes.map((route,index) => (
	          <Route
	            key={index}
	            path={route.path}
	            exact={route.exact} 
	            render={(props) => { // 利用render 方法处理
	              if (route.children){
	                return (
	                  <div>
	                    <route.component props={props}></route.component>
	                    <Switch>
	                      {
	                        route.children.map((child,i) => (
	                        	<Route
	                            	key={i}
	                            	path={child.path}
	                            	exact={child.exact}
	                            	component={child.component}
	                         	 />
	                        ))
	                      }
	                      <Redirect to={route.children[0].path}></Redirect> // 子路由找不到,重定向到第一个子路由
	                    </Switch>
	                  </div>
	                )
	              }else {
	                return (
	                  <route.component props={props}></route.component>
	                )
	              }
	            }}
		   />
	    ))
	    }
      	<Redirect from='/' to='/Index'></Redirect> // 根路径重定向到 /Index
      </Switch>
    </App>
  </HashRouter>,
  document.getElementById('root')
);

基本实现配置,简单来说,利用map方法遍历Route对象,子路由也是如此,这里要注意子组件的props为空情况,这里利用Route的props传递,也可以使用withRouter()方法解决

React-router 页面跳转的三种方式
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端小小白zyw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值