赋予代码灵魂 , 追求极致性能

Hey guys, Here is Vtrois's Blog !

总结React-Router v4 的正确使用姿势。

1.react-router v4 变化

1.Router被拆分成了StaticRouter、MemoryRouter、BrowserRouter、HashRouter、NativeRouter、StaticRouter。
MemoryRouter、BrowserRouter、HashRouter 等于

import { Router } from 'react-router'
<!--这里可以有三种-->
<!--history 部分源码
exports.createBrowserHistory = _createBrowserHistory3.default;
exports.createHashHistory = _createHashHistory3.default;
exports.createMemoryHistory = _createMemoryHistory3.default;
-->
import createBrowserHistory from 'history/createBrowserHistory'
//
const history = createBrowserHistory()

<Router history={history}>
  <App/>
</Router>

NativeRouter:是给 react-navtive用的
StaticRouter: 静态路由,永不改变位置的路由 主要用在服务器端,或简单测试。
到了4.0版本 在react-router-dom中直接将这几种作了内置。
**2.:呈现匹配位置的第一个子项或。这是v4版本中新添加,主要用来做唯一匹配的功能。就是想要在众多路由中只匹配其中一个路由。 **

2.React-Router v4基础写法

import React from 'react'
import {BrowserRouter as Router,Route,Link} from 'react-router-dom'
const Basic = () => (
  <Router>
    <div>
      <ul>
        <li><Link to="/">Home</Link></li>
        <li><Link to="/page1">Page1</Link></li>
        <li><Link to="/page2">Page2</Link></li>
      </ul>

      <hr/>

      <Route exact path="/" component={Home}></Route>
      <Route path="/page1" component={Page1}></Route>
      <Route path="/page2" component={Page2}></Route>
    </div>
  </Router>
)

4.0的Router下面可以放任意标签了,这意味着使用方式的转变,它更像redux中的provider了
真正的路由通过Route来定义。Link依然可以理解为a标签,点击会改变浏览器Url的hash值,通过Route标签来捕获这个url并返回component属性中定义的组件,exact关键字是将”/”做唯一匹配,否则”/”和”/xxx”都会匹配到path为”/”的路由。

通过Route路由的组件,可以拿到一个match参数,这个参数是一个对象,其中包含几个数据:
isExact:刚才已经说过这个关键字,表示是为作全等匹配
params:path中包含的一些额外数据
path:Route组件path属性的值
url:实际url的hash值


const Page2 = ({ match }) => ( <div> <h2>Page2</h2> <ul> <li> <Link to={`${match.url}/branch1`}> branch1 </Link> </li> <li> <Link to={`${match.url}/branch2`}> branch2 </Link> </li> <li> <Link to={`${match.url}/branch3`}> branch3 </Link> </li> </ul> <Route path={`${match.url}/:branchId`} component={Branch} /> <Route exact path={match.url} render={() => ( <h3>Default Information</h3> )} /> </div> ) const Branch = ({ match }) => { console.log(match); return ( <div> <h3>{match.params.branchId}</h3> </div> ) }

在例子中你可能注意到了Route的几个prop

exact: propType.bool
path: propType.string
component: propType.func
render: propType.func

注意:它们都不是必填的,如果path没有赋值,那么此Route就是默认渲染的。

Link的几个Prop

static propTypes = {
    onClick: PropTypes.func,
    target: PropTypes.string,
    replace: PropTypes.bool,
    to: PropTypes.oneOfType([
      PropTypes.string,
      PropTypes.object
    ]).isRequired
}

onClick就不说了,target属性就是a标签的target属性,to相当于href。
而replace的意思跳转的链接是否覆盖history中当前的url,若为true,新的url将会覆盖history中的当前值,而不是向其中添加一个新的。

3.V4 路由配置

1.基本配置(这个和v3中基本一致,效果也基本一样)

匹配 <= location eq.( /b => / + /b ) ( / => / )

  <BrowserRouter forceRefresh={!supportsHistory} keyLength={12}>
      <div>
         <Route path="/" component={aContainer} />
         <Route path="/b" component={bContainer} />
      </div>
    </BrowserRouter>

2.含Switch 配置

匹配 <= location eq.( /b => /b ) ( / => / ) 唯一匹配

<BrowserRouter forceRefresh={!supportsHistory} keyLength={12}>
      <Switch>
         <Route exact path="/" component={aContainer} ></Route>
         <Route path="/b" component={bContainer} ></Route>
      </Switch>
</BrowserRouter>

3.router 配置文件

v4中推荐配置文件配置路由,先将路由写在一个配置文件中,在需要展示的地方map出来

const routers = [{
  path: '/',
  breadcrumbName: "首页/",
  exact: true,
  render: () => api.isLogin() ? <Redirect to="/home"/> : <Redirect to="/login"/>,
}, {
  path: '/home',
  exact: true,
  breadcrumbName: "首页/",
  render: () => api.isHeadquarters() ? <OverView/> : <Home/>,
}, {
  path: '/customer/detail/',
  breadcrumbName: '客户管理/详情',
  exact: true,
  render: (props) => <LazyRoute {...props} component={import('./containers/customer/Detail')}/>
}, {
  path: '/customer/detail/:customerId',
  breadcrumbName: '客户管理/详情',
  exact: true,
  render: (props) => <LazyRoute {...props} component={import('./containers/customer/Detail')}/>
}]


routes.map((route, index) => (
                      <PrivateRoute
                        key={index}
                        path={route.path}
                        exact={route.exact}
                        component={route.render}
                      /> )
                      )

配置文件可以写多个组件,在一个页面我们可以显示一个路由中的不同组件

4.使用react-router-config 配置文件配置

安装:npm install –save react-router-config

第一步 配置路由

const routes = [
  { component: bContainer,
    routes: [
      { path: '/',
        exact: true,
        component: bContainer
      },
      { path: '/b/b',
        component: bContainer,
        routes: [
          { path: '/b/b/b',
            component: bContainer
          }
        ]
      }
    ]
  }
]

第二步 设置路由

<BrowserRouter forceRefresh={!supportsHistory} keyLength={12}>
      <div >
          {renderRoutes(routes)}
      </div>
 </BrowserRouter>

第三步 需要在container的render中去调用方法

<div>
  1111
  {renderRoutes(this.props.route.routes)}
</div>
点赞

发表评论

电子邮件地址不会被公开。