因爲React Router 4.0已經正式發佈,因此該博文分React Router 和 React Router 4.0 進行分類討論!該博文會持續更新中,歡迎你們一塊兒討論與補充!
我相信用過react通常都用過react-router,那就頗有必要說說用react-router實現的一些經常使用功能了,好比組件按需加載、用戶登陸驗證、刷新當前路由。。。在這篇文章中,我將列出一些react-router使用小技巧,但願每一個讀者都能至少從中學到一個有用的技巧!react
getComponent + require.ensure
實現按需加載 getComponent
相比之前的 component
屬性,這個方法是異步的,也就是當路由匹配時,纔會調用這個方法。webpack
require.ensure(dependencies, callback, chunkName)
而 require.ensure
是 webpack 提供的方法,這也是按需加載的核心方法。第一個參數是依賴的模塊數組,第二個是回調函數,該函數調用時會傳一個require參數,第三個是模塊名,用於構建時生成文件時命名使用web
實現按需加載核心代碼以下:npm
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;
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
實現按需加載核心代碼以下:babel
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 <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;
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 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-router
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 <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> ); } } // 登陸驗證 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;
實現點擊左側菜單刷新當前組件核心代碼以下:dom
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 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;
history.replace
實現點擊左側菜單刷新當前組件便可;歡迎你們一塊兒討論react-router使用小技巧,該博文會持續更新!異步