由于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
是 webpack 提供的方法,这也是按需加载的核心方法。第一个参数是依赖的模块数组,第二个是回调函数,该函数调用时会传一个require参数,第三个是模块名,用于构建时生成文件时命名使用
实现按需加载核心代码如下:
@H_403_18@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
,未安装请先安装:
实现按需加载核心代码如下:
@H_403_18@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 钩子在渲染对象组件前做拦截操作实现登录验证;
@H_403_18@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 属性上添加一个函数实现登录验证;
@H_403_18@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 钩子实现点击左侧菜单刷新当前组件;
@H_403_18@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使用小技巧,该博文会持续更新!
原文链接:https://www.f2er.com/react/302112.html