ReactRouter4

# Hello

路由是根據(jù)不同的網(wǎng)址顯示不同的組件,并有一系列API的封裝

import React from 'react';
import { HashRouter as Router, Link, Route } from "react-router-dom"

const Home = () => <h1>首頁</h1>;
const Prod = () => <h1>產(chǎn)品</h1>;
const User = () => <h1>用戶</h1>;

function App() {

  return (
    <>
      <Router>
        <Link to="/">首頁</Link>
        <Link to="/pro">產(chǎn)品</Link>
        <Link to="/user">用戶</Link>
        <Route path="/" exact component={Home} />
        <Route path="/pro" component={Prod} />
        <Route path="/user" component={User} />
      </Router>
    </>
  )
}

export default App;

Link 的 to 屬性就是要跳轉(zhuǎn)的路由

Rote 中的 path 對應(yīng) to ,表示要渲染的組件

exact 表示完全匹配,如果沒有,那么 / 或匹配 /* 而不是 /

# Router

組成

BrowserRouter

HashRouter

MemoryRouter

NativeRouter

StaticRouter

其中 BrowserRouter 和 HashRouter 屬于瀏覽器路由

瀏覽器路由

BrowserRouter 的路由類似 http://localhost:3000/user

HashRouter 的路由類似 http://localhost:3000/#/user

屬性

pathname 路由的地址其實是 pathname + path

比如 Router 加上 pathname="api"

使用前:http://localhost:3000/#/user

使用后:http://localhost:3000/#/api/user

<Router basename="/api">
  <Link to="/">首頁</Link>
  <Link to="/pro">產(chǎn)品</Link>
  <Link to="/user">用戶</Link>
  <Route path="/" exact component={Home} />
  <Route path="/pro" component={Prod} />
  <Route path="/user" component={User} />
</Router>

forceRefresh 布爾值,是否刷新整個頁面,如果為 true ,每次跳轉(zhuǎn)路由都會刷新頁面

<Router forceRefresh={true}>
  <Link to="/">首頁</Link>
  <Link to="/pro">產(chǎn)品</Link>
  <Link to="/user">用戶</Link>
  <Route path="/" exact component={Home} />
  <Route path="/pro" component={Prod} />
  <Route path="/user" component={User} />
</Router>

getUserConfirmation 當(dāng)導(dǎo)航需要確認(rèn)時執(zhí)行的函數(shù),需配合 Prompt 使用

Prompt 寫在需要提示的路由中,也可不寫 getUserConfirmation ,如果不寫,默認(rèn)是window彈框

寫了 getUserConfirmation 后,可以在處理跳轉(zhuǎn)前的邏輯

import React from 'react';
import { HashRouter as Router, Link, Route, Prompt } from "react-router-dom"

const Home = () => <h1>首頁<Prompt message="您是否離開首頁?"></Prompt></h1>;
const Prod = () => <h1>產(chǎn)品</h1>;
const User = () => <h1>用戶</h1>;

const getConfirmation = (message, callback) => {
  const allowTransition = window.confirm(message)
  callback(allowTransition)
}

function App() {

  return (
    <>
      <Router getUserConfirmation={getConfirmation}>
        <Link to="/">首頁</Link>
        <Link to="/pro">產(chǎn)品</Link>
        <Link to="/user">用戶</Link>
        <Route path="/" exact component={Home} />
        <Route path="/pro" component={Prod} />
        <Route path="/user" component={User} />
      </Router>
    </>
  )
}

export default App;

hashType HashRouter獨有,一共有三個值

slash #/api/user

noslash #api/user

hashbang #!/api/user

# Link

屬性 to

路由跳轉(zhuǎn)地址,可以是字符串

<Link to="/user">用戶</Link>

可是是對象

<Link to={{
  pathname:"/user"
}}>用戶</Link>

對象有如下屬性:

pathname 跳轉(zhuǎn)地址

search 參數(shù)傳遞

hash 跳轉(zhuǎn)的錨點

state 狀態(tài),可以通過 params.location.state 獲取

const User = (params) => {
  return params.location.state ? <h1>{params.location.state.name}</h1> : null;
}

屬性 replace

布爾值,如果為 true,則訪問歷史替換原地址

如果為false(默認(rèn)),訪問歷史記錄添加一項

<Link to="/user" replace />

# NavLink

特殊的 Link

如果在當(dāng)前路由狀態(tài),會默認(rèn)的添加一個 active 樣式

屬性:

activeStyle 如果在當(dāng)前路由狀態(tài),可以添加額外的style

activeClassName 如果在當(dāng)前路由狀態(tài),可以添加額外的 class 并替換 active

exact 完全匹配 activeStyle 和 activeClassName 才會生效

# Route

三種使用方式

使用component,默認(rèn)把參數(shù)傳到組件中

<Link to="/">首頁</Link>

const Home = (props) => {
  console.log(props);
  return <h1>首頁</h1>;
}

使用 render ,需自行把參數(shù)添加到組件中

const Prod = (props) => {
  console.log(props);
  return <h1>產(chǎn)品</h1>;
}

<Route path="/pro" render={(props) => <Prod {...props}></Prod>} />

使用 children,每次都會執(zhí)行,有一個參數(shù) match 可以判斷是否是指定路由

const User = (props) => {
  console.log(props);
  return <h1>用戶</h1>;
}

<Route path="/user" children={(props) => {
  return props.match ? <User {...props}></User> : null;
}} />

match

先看一下 match 的結(jié)構(gòu)

{
    isExact: true,
    params: { id: "2" },
    path: "/pro/:id",
    url: "/pro/2"
}

isExact 是否全匹配

params 參數(shù)

path 匹配路徑格式

url 匹配路徑

作用一: 路由參數(shù)

可以使用 props.match.params 獲取參數(shù)

import React from 'react';
import { HashRouter as Router, Link, Route } from "react-router-dom"

const Home = () => <h1>首頁</h1>;
const User = () => <h1>用戶</h1>;

const ProdDetail = (props) => <p>產(chǎn)品:{props.match.params.id}</p>;

const Prod = () => {
  return (
    <>
      <Link to="/pro/1">產(chǎn)品1</Link>
      <Link to="/pro/2">產(chǎn)品2</Link>
      <Link to="/pro/3">產(chǎn)品3</Link>
      <Route path="/pro/:id" component={ProdDetail}></Route>
    </>
  )
}

function App() {

  return (
    <>
      <Router basename="/api">
        <Link to="/">首頁</Link>
        <Link to="/pro">產(chǎn)品1</Link>
        <Link to="/user">用戶</Link>

        <Route path="/" component={Home} exact />
        <Route path="/pro" component={Prod} />
        <Route path="/user" component={User} />
      </Router>
    </>
  )
}

export default App;

作用二:變量提取

const Prod = (props) => {
  const basePath = props.match.url;
  return (
    <>
      <Link to={`${basePath}/1`}>產(chǎn)品1</Link>
      <Link to={`${basePath}/2`}>產(chǎn)品2</Link>
      <Link to={`${basePath}/3`}>產(chǎn)品3</Link>
      <Route path={`${basePath}/:id`} component={ProdDetail}></Route>
    </>
  )
}

location

可以拿到 Link:to 中的內(nèi)容,如果是字符串則拿不到 state

<Link to={
  {
    pathname: "/user",
    hash: "#h1",
    search: "?name=lisi",
    state: { name: "張三" }
  }
}>用戶</Link>

const User = ({ location }) => {
  console.log(location);
  return <h1>用戶</h1>;
}

// 得到的結(jié)果為

{
  hash: "#h1",
  pathname: "/user",
  search: "?name=lisi",
  state: { name: "張三" }
}

history

操作路由的一些 API ,可以從傳遞的參數(shù)中解構(gòu)獲取

const User = ({ history }) => {
  console.log(history);
  return <h1>用戶</h1>;
}

屬性:

length 堆棧數(shù)量

action 當(dāng)前動作,是跳轉(zhuǎn)過來的(PUSH),還是切換過來的(REPLACE)還是移出的(POP)

方法:

push 跳轉(zhuǎn)路由

replace 替換棧頂路由

go 前進(jìn)或后退多少路由

goBack 后退1步,相當(dāng)于 go(-1)

goForward 前進(jìn)一步,相當(dāng)于 go(1)

block 阻止跳轉(zhuǎn)

# Redirect

重定向到新的地址

import React from 'react';
import { HashRouter as Router, Link, Route, Redirect } from "react-router-dom"

const Home = () => <h1>首頁</h1>;
const Prod = () => <h1>產(chǎn)品</h1>;
const User = () => <Redirect to="/pro"></Redirect>;

function App() {

  return (
    <>
      <Router basename="/api">
        <Link to="/">首頁</Link>
        <Link to="/pro">產(chǎn)品</Link>
        <Link to="/user">用戶</Link>

        <Route path="/" component={Home} exact />
        <Route path="/pro" component={Prod} />
        <Route path="/user" component={User} />
      </Router>
    </>
  )
}

export default App;

此時點用戶,會被重定向到產(chǎn)品路由

常用作配合狀態(tài)使用,當(dāng)狀態(tài)更新時,重定向到其他路由,比如登出

import React, { useState } from 'react';
import { HashRouter as Router, Link, Route, Redirect } from "react-router-dom"

const Home = () => {
  const [isLogin, setisLogin] = useState(true);
  return (
    isLogin ?
      <>
        <h1>恭喜xx登錄成功!</h1>
        <p onClick={() => setisLogin(false)}>登出</p>
      </> :
      <Redirect to="/login"></Redirect>
  )
};
const Login = () => {
  return (
    <>
      <h1>登錄頁</h1>
      <button>登錄</button>
    </>
  )
};

function App() {

  return (
    <>
      <Router basename="/api">
        <Link to="/">首頁</Link>

        <Route path="/" component={Home} exact />
        <Route path="/login" component={Login} />
      </Router>
    </>
  )
}

export default App;

# Switch

未使用 Switch 前,一個地址可以匹配多個路徑

比如以下代碼,路徑 /pro 可匹配 / 和 /pro ,除非給 Route 加上 exact

<>
  <Router basename="/api">
    <Link to="/">首頁</Link>
    <Link to="/pro">產(chǎn)品</Link>
    <Link to="/user">用戶</Link>

    <Route path="/" component={Home}></Route>
    <Route path="/pro" component={Prod}></Route>
    <Route path="/user" component={User}></Route>
  </Router>
</>

使用 Switch 之后,只會匹配到遇到的第一個路由

比如以下代碼,無論是 / 還是 /pro 還是 /user 都是匹配到了首頁

<>
  <Router basename="/api">
    <Link to="/">首頁</Link>
    <Link to="/pro">產(chǎn)品</Link>
    <Link to="/user">用戶</Link>
    <Switch>
      <Route path="/" component={Home}></Route>
      <Route path="/pro" component={Prod}></Route>
      <Route path="/user" component={User}></Route>
    </Switch>
  </Router>
</>

弱匹配的路由放在后面或者加上 exact 屬性

<>
  <Router basename="/api">
    <Link to="/">首頁</Link>
    <Link to="/pro">產(chǎn)品</Link>
    <Link to="/user">用戶</Link>
    <Switch>
      <Route path="/pro" component={Prod}></Route>
      <Route path="/user" component={User}></Route>
      <Route path="/" component={Home}></Route>
    </Switch>
  </Router>
</>

Switch 配合 404 頁面

<>
  <Router basename="/api">
    <Link to="/">首頁</Link>
    <Link to="/pro">產(chǎn)品</Link>
    <Link to="/user">用戶</Link>
    <Switch>
      <Route path="/pro" component={Prod}></Route>
      <Route path="/user" component={User}></Route>
      <Route path="/" component={Home} exact></Route>
      <Route component={View404}></Route>
    </Switch>
  </Router>
</>

# Prompt

組件確認(rèn)跳轉(zhuǎn)導(dǎo)航,在路由離開之前彈框,如果點擊是,則跳轉(zhuǎn),否則不跳轉(zhuǎn)

import React from 'react';
import { HashRouter as Router, Link, Route, Switch, Prompt } from "react-router-dom"

const Home = () => <h1>Home! <Prompt message="是否離開首頁!"></Prompt></h1>;
const User = () => <h1>User!</h1>;
const Prod = () => <h1>Prod!</h1>;

function App() {

  return (
    <>
      <Router basename="/api">
        <Link to="/">首頁</Link>
        <Link to="/pro">產(chǎn)品</Link>
        <Link to="/user">用戶</Link>
        <Switch>
          <Route path="/pro" component={Prod}></Route>
          <Route path="/user" component={User}></Route>
          <Route path="/" component={Home} exact></Route>
        </Switch>
      </Router>
    </>
  )
}

export default App;

當(dāng)首頁跳轉(zhuǎn)其他頁時,會提示是否離開首頁,如果選是,則離開,否則不離開

message 還可以是一個函數(shù),返回結(jié)果作為提示語,函數(shù)的參數(shù)的location

const Home = () => <h1>Home! <Prompt message={
  (location) => {
    return `是否離開首頁,去${location.pathname}`
  }
}></Prompt></h1>;

Prompt 還有一個屬性,when,默認(rèn)為 true , 如果為false,則不提示直接跳轉(zhuǎn)

const Home = () => <h1>Home! <Prompt when={false} message={
  (location) => {
    return `是否離開首頁,去${location.pathname}`
  }
}></Prompt></h1>;

可以和 getUserConfirmation 配合使用,自定義彈出提示

import React from 'react';
import { HashRouter as Router, Link, Route, Switch, Prompt } from "react-router-dom"

const Home = () => <h1>Home! <Prompt message="是否離開"></Prompt></h1>;
const User = () => <h1>User!</h1>;
const Prod = () => <h1>Prod!</h1>;

const getUserConfirmation = (message, call) => {
  const flag = window.confirm(message);
  call(flag);
}

function App() {

  return (
    <>
      <Router basename="/api" getUserConfirmation={getUserConfirmation}>
        <Link to="/">首頁</Link>
        <Link to="/pro">產(chǎn)品</Link>
        <Link to="/user">用戶</Link>
        <Switch>
          <Route path="/pro" component={Prod}></Route>
          <Route path="/user" component={User}></Route>
          <Route path="/" component={Home} exact></Route>
        </Switch>
      </Router>
    </>
  )
}

export default App;
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容