由于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 (
{this.props.children}
);
}
}
const history = browserHistory;
// 首页
const home = (location, cb) => {
require.ensure([], require => {
cb(null, require('./Home').default);
}, 'home');
}
const RouteConfig = (
);
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, Route, 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 Loading...;
}
// Handle the error state
else if (error) {
return Sorry, there was a problem loading the page.;
}
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 (
{this.props.children}
);
}
}
let Router = process.env.NODE_ENV !== 'production' ? BrowserRouter : HashRouter;
const RouteConfig = (
);
export default RouteConfig;
二、实现登录验证
React Router:利用 Route 的 onEnter 钩子在渲染对象组件前做拦截操作实现登录验证;
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 (
{this.props.children}
);
}
}
const history = browserHistory;
// 首页
const home = (location, cb) => {
require.ensure([], require => {
cb(null, require('./Home').default);
}, 'home');
}
// 登录验证
const requireAuth = (nextState, replace) => {
if(true) { // 未登录
replace({
pathname: '/login',
state: { nextPathname: nextState.location.pathname }
});
}
}
const RouteConfig = (
);
export default RouteConfig;
React Router4.0:在 Route 的 render 属性上添加一个函数实现登录验证;
实现登录验证核心代码如下:
import React, { Component } from 'react';
import { BrowserRouter, HashRouter, Switch, Route, 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 Loading...;
}
// Handle the error state
else if (error) {
return Sorry, there was a problem loading the page.;
}
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 (
{this.props.children}
);
}
}
// 登录验证
function requireAuth(Layout, props) {
if (true) { // 未登录
return ;
} else {
return
}
}
let Router = process.env.NODE_ENV !== 'production' ? BrowserRouter : HashRouter;
const RouteConfig = (
requireAuth(Home, props)} />
);
export default RouteConfig;
三、实现点击左侧菜单刷新当前组件
React Router:利用 Route 的 createElement 钩子实现点击左侧菜单刷新当前组件;
实现点击左侧菜单刷新当前组件核心代码如下:
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 (
{this.props.children}
);
}
}
const history = browserHistory;
// 首页
const home = (location, cb) => {
require.ensure([], require => {
cb(null, require('./Home').default);
}, '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 = (
);
export default RouteConfig;
React Router4.0:直接使用 history.replace
实现点击左侧菜单刷新当前组件即可;
欢迎大家一起讨论react-router使用小技巧,该博文会持续更新!