React進階篇(1) -- react-router4模組化
阿新 • • 發佈:2018-12-26
本篇內容:
- 單一的路由無巢狀
- 多層巢狀路由
- 獲取路徑中的引數
- 按需載入
單一的路由無巢狀
routers.js
import Home from 'components/Home'; import News from 'components/News'; import User from 'components/User'; import My from 'components/My'; let routes=[ { path:'/', component:Home , exact:true }, { path:'/news', component:News , }, { path:'/user', component:User }, { path:'/my', component:My }, ] export default routes;
App.jsx
import React, { Component } from 'react'; import { HashRouter as Router, Switch, Route } from "react-router-dom"; import routes from '../routers/index'; class App extends Component { render() { return ( <Router> <div> <Switch> //主要邏輯在這裡 { routes.map((item, i) => { if(item.exact){ return <Route exact path={item.path} component={item.component} key={i}/> }else{ return <Route path={item.path} component={item.component} key={i}/> } }) } </Switch> </div> </Router> ); } }
多層巢狀路由
let routes=[ { path:'/hear', component:Hear, exact:true, description:"聽", subs:[ { path:'/hear/', component:HearIndex, description:"聽-首頁" }, { path:'/hear/book', component:HearBook, description:"聽-課文" }, ] }, { path:'/speak', component:Speak, exact:true, description:"說", subs:[ { path:'/speak/', component:CN, description:"說-漢語" }, { path:'/speak/english', component:English, description:"說-英語" }, ] }, { path:'/read', component:Read, exact:true, description:"讀", subs:[ { path:'/read/', component:ReadBook, description:"讀-課文" }, { path:'/read/newspaper', component:ReadNews, description:"讀-報紙" }, ] }, { path:'/writ', component:Writ, exact:true, description:"寫" } ] export default routes;
App.jsx
{
routes.map((item, i) => {
if (item.exact) {
//官方固定格式
return <Route exact path={item.path} key={i} render={ props => (<item.component {...props} routes={item.subs}/>) />
}
else {
return <Route path={item.path} key={i} render={ props => (<item.component {...props} routes={item.subs}/>)} />
}
})
}
//step 2,在對應的元件中再次遍歷
{
this.props.routes.map((item, i) => {
return <Route exact path={item.path}
component= {item.component}
key={i}/>
})
}
跳轉
this.props.history.push(`/about/type/${id}`)
this.props.history.replace(...)
注意:
不能在子元件中直接獲取,需要從父級傳入之後用props獲取;
跳轉時,如果還有事件未結束,則容易報錯!
如:
<LoginCom TIMEID={TIMEID} {...this.props}/>
獲取路徑引數
獲取對應的params
this.props.match.params.id
獲取?後面對應的值
const getQueryString = (str,name) => {
let result = str.match(new RegExp("[\?\&]" + name + "=([^\&]+)", "i"));
if (result == null || result.length < 1) {
return "";
}
return decodeURI(result[1], "utf-8");
}
如:http://localhost:3000/#/textbook/bishun?val=看
console.log(getQueryString(this.props.location.search,'val'));
按需載入
感覺這種方式最簡單:
基於 webpack, babel-plugin-syntax-dynamic-import, 和 react-loadable;
主要是利用了react-loadable這個高階元件,他是專門用來非同步載入(也可以預載入)元件的。
cnpm i -S react-loadable @babel/plugin-syntax-dynamic-import
.babelrc
{
“ presets ”:[ “ @ babel / react ” ],
“ plugins ”:[ “ @ babel / plugin-syntax-dynamic-import ” ]
}
routers.js變化
import Loadable from 'react-loadable';
import DelayLoading from './DelayLoading';
const Home= Loadable({loader: () => import('../components/Home'), loading : DelayLoading,delay:3000})
const Login= Loadable({loader: () => import('../components/Login'), loading : DelayLoading,delay:3000})
打包檔案情況對比:
首屏載入情況對比:
參考文件:
https://reacttraining.com/react-router/web/example/route-config
https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/guides/code-splitting.md
https://github.com/jamiebuilds/react-loadable
可參考其他文章:https://www.cnblogs.com/alan2kat/p/7754846.html