这里有没有你想要的react-router

由于React Router 4.0已经正式发布,所以该博文分React Router 和 React Router 4.0 进行分类讨论!该博文会持续更新中,欢迎大家一起讨论与补充!

我相信用过react一般都用过react-router,那就很有必要说说用react-router实现的一些常用功能了,比如组件按需加载、用户登录验证、刷新当前路由。。。在这文章中,我将列出一些react-router使用小技巧,希望每个读者都能至少从中学到一个有用的技巧!

一、按需加载

React Router:使用 getComponent + require.ensure 实现按需加载

getComponent 相比以前的 component 属性,这个方法是异步的,也就是当路由匹配时,才会调用这个方法

require.ensure(dependencies,callback,chunkName)

require.ensure 是 webpack 提供的方法,这也是按需加载的核心方法。第一个参数是依赖的模块数组,第二个是回调函数,该函数调用时会传一个require参数,第三个是模块名,用于构建时生成文件时命名使用

实现按需加载核心代码如下:

import React,{ Component } from 'react'; // react核心
import { Router,Route,Redirect,IndexRoute,browserHistory } from 'react-router'; 

/**
 * (路由根目录组件,显示当前符合条件的组件)
 * 
 * @class Roots
 * @extends {Component}
 */
class Roots extends Component {
    render() {
        return (
            <div>{this.props.children}</div>
        );
    }
}

const history = browserHistory;

// 首页
const home = (location,cb) => {
    require.ensure([],require => {
        cb(null,require('./Home').default);
    },'home');
}

const RouteConfig = (
    <Router history={history}>
        <Route path="/" component={Roots}>
            <IndexRoute getComponent={home} />   
            <Route path="/home" getComponent={home} /> 
            <Route path="/login" component={login} />
            <Redirect from="*" to="/home" />
        </Route>
    </Router>
);

export default RouteConfig;

React Router 4.0:使用 babel-plugin-Syntax-dynamic-import + react-loadable 实现按需加载

首先确保已安装 babel-plugin-Syntax-dynamic-import react-loadable,未安装请先安装:

npm i -D babel-plugin-Syntax-dynamic-import

npm i -S react-loadable

实现按需加载核心代码如下:

import React,{ Component } from 'react';
import { browserRouter,HashRouter,Switch,Redirect} from 'react-router-dom';
import createbrowserHistory from 'history/createbrowserHistory'
const history = createbrowserHistory();

// 按路由拆分代码
import Loadable from 'react-loadable';

const loadingComponent = ({ isLoading,error }) => {
  // Handle the loading state
  if (isLoading) {
      return <div>Loading...</div>;
  }
  // Handle the error state
  else if (error) {
      return <div>Sorry,there was a problem loading the page.</div>;
  }
  else {
      return null;
  }
};

const Index = Loadable({
  loader: () => import('./Index'),loading: loadingComponent
});

const Home= Loadable({
  loader: () => import('./Home'),loading: loadingComponent
});

const Login= Loadable({
  loader: () => import('./Login'),loading: loadingComponent
});

/**
 * (路由根目录组件,显示当前符合条件的组件)
 * 
 * @class Roots
 * @extends {Component}
 */
class Roots extends Component {
    render() {
        return (
            <div>{this.props.children}</div>
        );
    }
}

let Router = process.env.NODE_ENV !== 'production' ? browserRouter : HashRouter;

const RouteConfig = (
    <Router history={history}>
        <Switch>
            <Route path="/" exact component={Index} />
            <Route path="/home" component={Home} />
            <Route path="/login" component={Login} />
            <Redirect from='' to="/" />
        </Switch>
    </Router>
);

export default RouteConfig;

二、实现登录验证

React Router:利用 Route 的 onEnter 钩子在渲染对象组件前做拦截操作实现登录验证;

import React,'home');
}

// 登录验证
const requireAuth = (nextState,replace) => {
    if(true) { // 未登录
        replace({
            pathname: '/login',state: { nextPathname: nextState.location.pathname }
        });
    } 
}

const RouteConfig = (
    <Router history={history}>
        <Route path="/" component={Roots}>
            <IndexRoute getComponent={home} onEnter={requireAuth} />   
            <Route path="/home" getComponent={home} onEnter={requireAuth} /> 
            <Route path="/login" component={login} />
            <Redirect from="*" to="/home" />
        </Route>
    </Router>
);

export default RouteConfig;

React Router4.0:在 Route 的 render 属性添加一个函数实现登录验证;

实现登录验证核心代码如下:

import React,loading: loadingComponent
});

/**
 * (路由根目录组件,显示当前符合条件的组件)
 * 
 * @class Roots
 * @extends {Component}
 */
class Roots extends Component {
    render() {
        return (
            <div>{this.props.children}</div>
        );
    }
}

// 登录验证
function requireAuth(Layout,props) {
  if (true) { // 未登录
    return <Redirect to="/login" />;
  } else {
    return <Layout {...props} />
  }
}

let Router = process.env.NODE_ENV !== 'production' ? browserRouter : HashRouter;

const RouteConfig = (
    <Router history={history}>
        <Switch>
            <Route path="/" exact component={Index} />
            <Route path="/home" component={props => requireAuth(Home,props)} />
            <Route path="/login" component={Login} />
            <Redirect from='' to="/" />
        </Switch>
    </Router>
);

export default RouteConfig;

三、实现点击左侧菜单刷新当前组件

React Router:利用 Route 的 createElement 钩子实现点击左侧菜单刷新当前组件;

实现点击左侧菜单刷新当前组件核心代码如下:

import React,'home');
}

// 此处为要点击刷新的组件
const arr = [
    home
];

// 开关优化
let onOff =false;

// 页面强制刷新,如果需要强制刷新在路由中添加onChange事件以及在组件数组添加
const createElement=(component,props) =>{
    if (props.children && onOff || props.children && arr.includes(props.routes.slice(-1)[0].getComponent)) {
        let children = Object.assign({},props.children,{key : `${window.location.pathname}` + new Date().getTime()})
        props = { ...props,children };
        onOff = false;
    }
    return React.createElement(component,props)
 }

 const onChange = (props,next) => {
     onOff = true
     console.log(`${next.location.pathname}`,'change');
 }

const RouteConfig = (
    <Router history={history} createElement = {createElement}>
        <Route path="/" component={Roots}>
            <IndexRoute getComponent={home} />   
            <Route path="/home" getComponent={home} /> 
            <Route path="/login" component={login} />
            <Redirect from="*" to="/home" />
        </Route>
    </Router>
);

export default RouteConfig;

欢迎大家一起讨论react-router使用小技巧,该博文会持续更新!

相关文章

react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接...
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc ...