# 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 路由的地址其實(shí)是 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獨(dú)有灰殴,一共有三個值
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)的錨點(diǎ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)),訪問歷史記錄添加一項(xiàng)
<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;
此時點(diǎn)用戶锁蠕,會被重定向到產(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)航苏揣,在路由離開之前彈框,如果點(diǎn)擊是推姻,則跳轉(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;