react-router-dom簡介(推薦)
react-router-dom
react-router-dom文檔地址: https://reacttraining.com/react-router/
1. 安裝
react-router提供多個包可以單獨使用
package | description |
---|---|
react-router | 路由核心功能 |
react-router-dom | 基于react-router提供在瀏覽器運行環(huán)境下功能 |
react-router-native | for React Native |
react-router-config | static route congif helpers |
在瀏覽器中運行只需要安裝react-router-dom,reac-router-dom依賴react-router會自動安裝依賴,所以不需要再手動安裝react-router
npm install react-router-dom -S // 或者 yarn add react-router-dom
2. 路由組件
react-router包含三種類型的組件:路由組件、路由匹配組件 、導(dǎo)航組件。在你使用這些組件的時候,都必須先從react-router-dom引入。
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
2.1 路由組件
react-router提供了兩種路由組件: BrowserRouter
, HashRouter
其中BrowserRouter
是基于HTML5 history API (pushState
, replaceState
, popstate
)事件
當(dāng)然與之對應(yīng)的還有HashRouter
是基于window.location.hash
。
2.2 路由匹配組件
路由匹配組件有兩種:Route
和Switch
,Switch
把多個路由組合在一起。
對于一個<Route>
組件,可以設(shè)置三種屬性:component
、render
、children
來渲染出對應(yīng)的內(nèi)容。
當(dāng)組件已存在時,一般使用component屬性當(dāng)需要傳遞參數(shù)變量給組件時,需要使用render屬性
2.3 導(dǎo)航組件
有三種常用的導(dǎo)航組件,分別是:<Link>
、<NavLink>
、<Redirect>
。<NavLink>
是一種特殊的Link組件,匹配路徑時,渲染的a標簽帶有active。
3. 使用
在需要使用router的地方引入react-router-dom
3.1 基本使用
以下是路由的基本使用例子
import React from 'react'; import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom"; // import logo from './logo.svg'; import './App.css'; import About from './views/About' import Home from './views/Home' import Person from './views/Person' function App() { return ( <Router> <div> <nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/about">About</Link> </li> <li> <Link to="/person">Person</Link> </li> </ul> </nav> {/* A <Switch> looks through its children <Route>s and renders the first one that matches the current URL. */} <Switch> <Route path="/about"> <About /> </Route> <Route path="/person"> <Person /> </Route> <Route path="/"> <Home /> </Route> </Switch> </div> </Router> ); } export default App;
當(dāng)然此處路由也可以有其他寫法,比如
<Switch> <Route exact path="/" component={Home}></Route> <Route path="/about" component={About}></Route> <Route path="/person/:id" component={Person}></Route> <Route component={NotFind}></Route> </Switch>
其中的exact
表示的是精確匹配,比如上面
<Route exact path="/" component={Home}></Route>
如果沒有寫精確匹配的化,那么后面的所有路徑都可以匹配到首頁,解決方式就是增加exact或者將此路由放置最后面。
3.2 Route動態(tài)傳參
在一個路由匹配組件上設(shè)置參數(shù),比如說上面的Person組件
<Route path="/person/:id" component={Person}></Route>
設(shè)置是以:開始然后緊跟key值,然后我們在Person組件中就可以通過獲取props獲取這個參數(shù)值
import React from 'react'; export default class Person extends React.Component { constructor(props) { super(props); console.log(this.props.match.params.id) } render() { const id = this.props.match.params.id return ( <div> <h2>個人中心頁面</h2> <p>個人id是:{id}</p> </div> ) } }
以上為傳統(tǒng)class組件的寫法,現(xiàn)在可以使用hooks,可以使用useParams
,代碼如下:
import React from 'react'; import { useParams } from 'react-router-dom' const Person = () => { const { id } = useParams(); return ( <div> <h2>個人中心頁面</h2> <p>個人id是:{id}</p> </div> ) }
3.3 嵌套路由
在About頁面有一個嵌套路由代碼示例:
import React from 'react'; import { Link, Switch, Route } from 'react-router-dom' import Tshirt from './product/Tshirt'; import Jeans from './product/Jeans' export default class About extends React.Component { constructor(props) { super(props) console.log(this.props.match) } render() { const match = this.props.match; return ( <> <nav> <Link to={`${match.url}/tshirt`}>Tshirt</Link>| <Link to={`${match.url}/jeans`}>Jeans</Link> </nav> <Switch> <Route path={`${match.path}/tshirt`} component={Tshirt}></Route> <Route path={`${match.path}/jeans`} exact component={Jeans}></Route> </Switch> </> ) } }
此處如果換成Function的話可以直接使用另一個鉤子函數(shù)useRouteMatch
,獲取當(dāng)前匹配的路徑和路由
import { useRouteMatch } from 'react-router-dom' const About = () => { const { path, url } = useRouteMatch(); ...省略 }
3.4 路由重定向
Redirect
路由重定向,使路由重定向到某個頁面,比如我們經(jīng)常會做的沒有登錄重定向到登錄頁面
<Route exact path="/"> {loggedIn ? <Redirect to="/dashboard" /> : <PublicHomePage />}</Route>
3.5 滾動還原
大部分情況下,我們需要的是每次導(dǎo)航到某個新頁面的的時候,滾動條都是在頂部,這種比較好實現(xiàn)
hooks版本
import { useEffect } from "react";import { useLocation } from "react-router-dom"; export default function ScrollToTop() { const { pathname } = useLocation(); useEffect(() => { window.scrollTo(0, 0); }, [pathname]); return null; }
class版本
import React from "react";import { withRouter } from "react-router-dom"; class ScrollToTop extends React.Component { componentDidUpdate(prevProps) { if ( this.props.location.pathname !== prevProps.location.pathname ) { window.scrollTo(0, 0); } } render() { return null; }}
我們需要把ScrollToTop
組件放在Router里面eg:
function App() { return ( <Router> <ScrollToTop /> <App /> </Router> );}
而對于某些情況下比如一些tab我們希望切換回我們?yōu)g覽過的tab頁時我們希望滾動條滾動到我們之前瀏覽的位置,此處自行去實現(xiàn)。
3.6 路由守衛(wèi)
有時候我們在某個表單頁面填好了表單,然后點擊跳轉(zhuǎn)到另外一個頁面。
這時候我們就需要提醒用戶有未提交的表單。當(dāng)然這一步其實也是在實際的業(yè)務(wù)代碼中實現(xiàn)。
import React, { useState } from "react"; import { Prompt } from "react-router-dom"; const BlockingForm = ()=>{ let [isBlocking, setIsBlocking] = useState(false); return ( <form onSubmit={event => { event.preventDefault(); event.target.reset(); setIsBlocking(false); }} > <Prompt when={isBlocking} message={location => `你是否要跳轉(zhuǎn)到 ${location.pathname}` } /> <p> Blocking?{" "} {isBlocking ? "Yes, click a link or the back button" : "Nope"} </p> <p> <input size="50" placeholder="輸入值測試路由攔截" onChange={event => { setIsBlocking(event.target.value.length > 0); }} /> </p> <p> <button>提交表單模擬接觸攔截</button> </p> </form> ); } export default BlockingForm;
3.7代碼分割
有時候為了避免文件過大加快加載速度,我們需要將代碼分割,將某些路由對應(yīng)的組件只有在點擊的時候再加載js,就是組件的懶加載。
我們使用webpack
, @babel/plugin-syntax-dynamic-import
,loadable-components
實現(xiàn)代碼分割。
首先在.babelrc文件中增加配置
{ "presets": ["@babel/preset-react"], "plugins": ["@babel/plugin-syntax-dynamic-import"] }
在我們需要懶加載的組件使用loadabel
import React from 'react'; import loadable from '@loadable/component'; const BlockForm = loadable(() => import('../pages/BlockForm/index'), { fallback: <Loading /> })
其中BlockForm為懶加載得組件loadable
參考文檔地址 跳轉(zhuǎn)
3.8 withRouter
您可以通過withRouter高階組件訪問history屬性和匹配的Route,
withRouter will pass updated match, location, and history props to the wrapped component whenever it renders.
eg:
import React from "react";import PropTypes from "prop-types";import { withRouter } from "react-router"; // A simple component that shows the pathname of the current locationclass ShowTheLocation extends React.Component { static propTypes = { match: PropTypes.object.isRequired, location: PropTypes.object.isRequired, history: PropTypes.object.isRequired }; render() { const { match, location, history } = this.props; return <div>You are now at {location.pathname}</div>; }} // Create a new component that is "connected" (to borrow redux// terminology) to the router.const ShowTheLocationWithRouter = withRouter(ShowTheLocation);
3.9 其他hooks
之前使用了useParams
和useRouteMatch
兩個hook,還有另外兩個hookuseHistory
和useLocation
useHistory
可以訪問到history實例,我們可以通過這個實例訪問某個路由
useLocation
返回location對象
到此這篇關(guān)于react-router-dom簡介的文章就介紹到這了,更多相關(guān)react-router-dom內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
React?Hooks的useState、useRef使用小結(jié)
React Hooks 是 React 16.8 版本引入的新特性,useState和useRef是兩個常用的Hooks,本文主要介紹了React?Hooks的useState、useRef使用,感興趣的可以了解一下2024-01-01React使用useImperativeHandle自定義暴露給父組件的示例詳解
useImperativeHandle?是?React?提供的一個自定義?Hook,用于在函數(shù)組件中顯式地暴露給父組件特定實例的方法,本文將介紹?useImperativeHandle的基本用法、常見應(yīng)用場景,需要的可以參考下2024-03-03React中實現(xiàn)編輯框自動獲取焦點與失焦更新功能
在React應(yīng)用中,編輯框的焦點控制和數(shù)據(jù)回填是一個常見需求,本文將介紹如何使用useRef和useEffect鉤子,在組件中實現(xiàn)輸入框自動獲取焦點及失焦后更新數(shù)據(jù)的功能,文中通過代碼示例給大家講解的非常詳細,需要的朋友可以參考下2024-01-01