由于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使用小技巧,该博文会持续更新!