react中路由和按需加載的問題
react路由和按需加載問題
1 基本的路由設(shè)置
react-router可以解決路由問題,只需要添加[基于react-router4.x]
yarn add react-router-dom
然后在index.js中引入它,使用:
import {Link,BrowserRouter,Switch, Route} from 'react-router-dom';
ReactDOM.render((
<BrowserRouter>
<Switch>
<Route path="/list" component={ListDemo}/>
<Route path="/a" component={A}/>
<Route path="/b" component={B}/>
</Switch>
</BrowserRouter>
),mountdom)這樣就完成了路由的設(shè)置,而超鏈接則可以使用提供的Link組件
<Link to="/a">a</Link>
等價于直接寫<a href="/a">a</a>。
2 如何完成路由的菜單部分
在每個menu中傳一個url屬性,然后url代表那個地方被高亮,每個路由都重新創(chuàng)建一個menu即如下:
<BrowserRouter>
<Switch>
<Route exact path="/" render={props=><Menu {...props} url="list"><ListDemo/></SiderDemo>}/>
<Route path="/list" render={props=><Menu {...props} url="list"><ListDemo/></SiderDemo>}/>
<Route path="/a" render={props=><Menu {...props} url="a"><A/></SiderDemo>}/>
<Route path="/b" render={props=><Menu {...props} url="b"><B/></SiderDemo>}/>
</Switch>
</BrowserRouter>但是每個頁面的初次加載都會閃一下,重新加載了js。要想不閃則需要路由嵌套:
//上來路由只匹配到Menu中
<BrowserRouter>
<Switch>
<Route path="/" component={Menu}/>
</Switch>
</BrowserRouter>
//上面的route就一個組件menu,在menu中再次定義route,可以實現(xiàn)路由嵌套
<Menu>
<頂部></頂部>
<側(cè)欄 selectedurl={this.props.location.pathname}>
</側(cè)欄>
<內(nèi)容部分>
<Route exact path="/list" component={List}/>
<Route exact path="/a" component={At}/>
<Route exact path="/b" component={Bt}/>
</內(nèi)容部分>
<Menu>這里主要是利用了每個頁面都有的一個屬性即props.location.pathname是路由屬性
3 如何將每個路由的js文件分開輸出
1 多入口文件的形式,但是不易于按需加載,只能是實現(xiàn)了分開輸出,沒啥用。一般寫的都是單入口應(yīng)用。
2 異步import,或者require.ensure,然后在webpack中配置
output:{
filename:"[name]-bundle.js",
chunkFilename: "[name]-chunk.js",
path: __dirname+'/dist'
},這樣就生成一個bundle文件,多個chunk文件,name就是import的文件的名字,注意這里的注釋是有用的直接決定了chunk輸出的時候的[name]。
import(/* webpackChunkName: "app" */'./app').then(function(res){
let xx= res.default;//xx就是app的export default
})4 react-router按需加載配置
create-react-app創(chuàng)建的應(yīng)用執(zhí)行npm run eject進行彈射。webpack中已經(jīng)有了上面3中的配置,是可以直接生成多個chunk文件的。
創(chuàng)建一個函數(shù)用于生成異步組件:
import React, { Component } from "react";
export default function asyncComponent(importComponent) {
class AsyncComponent extends Component {
constructor(props) {
super(props);
this.state = {
component: null
};
}
async componentDidMount() {
const { default: component } = await importComponent();
this.setState({
component: component
});
}
render() {
const C = this.state.component;
return C ? <C {...this.props} /> : null;
}
}
return AsyncComponent;
}改變組件引入方式之前是直接import現(xiàn)在改為
const List=asyncComponent(()=>import(/* webpackChunkName: "list" */"./router/List")) const At=asyncComponent(()=>import(/* webpackChunkName: "a" */"./router/A")) const Bt=asyncComponent(()=>import(/* webpackChunkName: "b" */"./router/B"))
渲染
<HashRouter>
<Switch>
<Route path="/" component={SiderDemo}/>
</Switch>
</HashRouter>
class SiderDemo extends React.Component {
render() {
let selected=this.props.location.pathname.substring(1)
if(selected==="")selected="list"
return (
<Layout>
<Sider>
<Menu defaultSelectedKeys={[selected]}>
.........................
</Menu>
</Sider>
<Layout>
<Header></Header>
<Content >
<div>
<Route exact path="/list" component={List}/>
<Route exact path="/a" component={At}/>
<Route exact path="/b" component={Bt}/>
<Route exact path="/" component={List}/>
</div>
</Content>
<Footer></Footer>
</Layout>
</Layout>
);
}
}5 最后效果

react路由的基本使用
1.先下包
react-router-dom@5.3.0 可以自己用npm yarn cnpm 進行下載,我使用的是5.3.0版本
2.導(dǎo)入并使用
import { HashRouter as Router , Route, Link } from 'react-router-dom'
?
export default function App () {
? return (
? ? <div>
? ? ? <h1>react路由基本使用</h1>
? ? ? <Router>
? ? ? ? <Link to="/comment">評論</Link>
? ? ? ? <Link to="/search">搜索</Link>
?
? ? ? ? <Route path="/comment" component={Comment} />
? ? ? ? <Route path="/search" component={Search} />
? ? ? </Router>
? ? </div>
? )
}
ReactDom.render(<App />, document.getElementById('root'))這樣就實現(xiàn)了一個簡易的點擊路由跳轉(zhuǎn)
3.使用HashRouter包裹整個應(yīng)用
(一個項目中只會有一個 我上面是經(jīng)過as改名之后的)
兩種常用 Router:HashRouter 和 BrowserRouter
HashRouter:使用 URL 的哈希值實現(xiàn)- 監(jiān)聽 window 的 hashchange 事件來實現(xiàn)的
BrowserRouter:使用 H5 的 history.pushState() API 實現(xiàn)- 監(jiān)聽 window 的 popstate 事件來實現(xiàn)的
4.使用Link指定導(dǎo)航鏈接
指定導(dǎo)航鏈接方式有兩種 分別是Link 和 NavLink
Link組件最終會渲染成a標簽,用于指定路由導(dǎo)航
Link組件無法展示哪個link處于選中的效果
NavLink組件,可以用用于指定當前導(dǎo)航高亮
(當前組件被點擊時 會添加一個 active 類,可以通過修改這個類 可以修改被選中是的樣式)
<NavLink to="/xxx" activeClassName="active">鏈接</NavLink>
5.使用Route指定路由規(guī)則(哪個路徑展示哪個組件)
默認路由路徑匹配規(guī)則是: 模糊匹配規(guī)則
- 只要pathname以path開頭就算匹配成功
- 匹配成功就加載對應(yīng)組件;
- 整個匹配過程是逐一匹配,一個匹配成功了,并不會停止匹配。
6.精確匹配 :exact
只有路徑完全一致才被匹配上
7.Switch
用Switch組件包裹多個Route組件。
在Switch組件下,不管有多少個Route的路由規(guī)則匹配成功,都只會渲染第一個匹配的組件
? ? ? ? <Switch>
? ? ? ? ? <Route path="/" exact component={Home} />
? ? ? ? ? <Route path="/article" component={Article} />
? ? ? ? ? <Route path="/article/123" component={ArticleDetail} />
? ? ? ? </Switch>8.處理404頁
思路: 不設(shè)置path屬性,將404頁對應(yīng)的路由放在switch內(nèi)部的最后位置
? ? ? ? <Switch>
? ? ? ? ? <Route path="/" exact component={Home} />
? ? ? ? ? <Route path="/article" component={Article} />
? ? ? ? ? <Route path="/article/123" component={ArticleDetail} />
? ? ? ? ? <Route component={Page404} />
? ? ? ? </Switch>Redirect
<Redirect from="/" exact to="/comment" /> 當精準匹配到/ 時 ,跳轉(zhuǎn)到comment路徑
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
React-Native TextInput組件詳解及實例代碼
這篇文章主要介紹了React-Native TextInput組件詳解及實例代碼的相關(guān)資料,需要的朋友可以參考下2016-10-10
react中使用redux-persist做持久化儲存的過程記錄
這篇文章主要介紹了react中使用redux-persist做持久化儲存的相關(guān)資料,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2024-01-01
React useMemo和useCallback的使用場景
這篇文章主要介紹了React useMemo和useCallback的使用場景,幫助大家更好的理解和學(xué)習(xí)使用React框架,感興趣的朋友可以了解下2021-04-04

