Router 路由库
npm install react-router-dom
BrowserRouter
<BrowserRouter>
作为 context provider, 其中的 children 可利用路由.
import React from "react"
import ReactDOM from "react-dom"
import { BrowserRouter } from "react-router-dom"
import App from "./App"
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("root")
)
Link, Switch, Route
- 跳转链接,
to
为目标链接, DOM 中渲染为<a>
- 默认情况下
path
以传入到为起始, exact 则完全匹配 component
传入无法接收 props, 传入children
则可以传入 propsLink
在哪里都可以 只是跳转链接Switch
可以相像成switch
流程控制, 即根据当前的 path 渲染相对应的组件.- 通常写在一个单独的
Navigator.jsx
文件.
Navigator.jsx
import { Link, Switch, Route } from "react-router-dom"
import Home from "./Home"
import About from "./About"
const Navigator = () => {
return (
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/about">
<About />
</Route>
</Switch>
)
}
App.jsx
const App = () => {
return (
<div>
{/* 共享的组件 即每个路径都渲染 一般为导航栏组件 */}
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
{/* 路由条件渲染组件 */}
<Navigator />
</div>
)
}
useParams
动态路由 分三步
Route
中配置动态路由存储的变量, 之后用useParams
提取- 动态生成
Link
- 详情页面 使用
useParams
提取路由的变量
Navigator.jsx
import { Link, Switch, Route } from "react-router-dom"
const Navigator = () => {
return (
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route exact path="/subjects">
<SubjectList />
</Route>
{/* 将路由的链接存储为subjectId */}
<Route path="/subjects/:subjectId">
<SubjectDetail />
</Route>
</Switch>
)
}
SubjectList.jsx
const SubjectList = () => {
const [subject, setSubject] = useState([])
useEffect(() => {
// API请求获取数据
}, [])
return (
<div>
<h1>All Subjects</h1>
{/* 动态生成 Link */}
{subject.map(s => (
<Link to={`/subjects/${s.id}`}>{s.title}</Link>
))}
</div>
)
}
SubjectDetail.jsx
import { useParams } from "react-router-dom"
const SubjectDetail = () => {
const param = useParams()
const subjectId = param.subjectId
// const {subjectId} = useParams 或者用Object Destruction
useEffect(() => {
// 根据id请求该Subject的详细信息
})
return <div>{/* UI */}</div>
}
export default SubjectDetail
useHistory
动态跳转. 例如 longin 登录后自动跳转. 需要在函数中处理更改链接.
import { useHistory } from "react-router-dom"
const Authentication = () => {
const history = useHistory()
const handleLogin = () => {
// 账户验证...
history.push("/") // 当前路径更改为 / 主页面
}
return (
<form>
<input placeholder="User name" />
<input placeholde="Password" />
<button onClick={handleLogin}>Log In</button>
</form>
)
}
useLocation
获取当前 path 的信息如下
pathname
即当前的路径名, 如果需要判断当前路径名search
即路径中的Query String,?
之后的. 通常用于前端的 filter 或者排序展示特定的数据.
{
"pathname": "/subjects",
"search": "?sort=date&page=1",
"hash": "",
"state": null,
"key": "qd3dcd5"
}
import { useLocation } from "react-router-dom"
const SubjectList = () => {
const location = useLocation()
return (
<div>
<h1>All Subjects</h1>
</div>
)
}
Redirect
登录认证 自动跳转
对于每次/private
路由, 如果 isLoggedIn
true, 则渲染 <Private />
否则则自动跳转到 /login
import { Link, Switch, Route, Redirect } from "react-router-dom"
const App = () => {
const [isLoggedIn, setIsLoggedIn] = useState(false)
return (
<div>
<Link to="/">Home</Link>
<Link to="/private">Private</Link>
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route exact path="/private">
{isLoggedIn ? <Private /> : <Redirect to="/login" />}
</Route>
<Route exact path="/login">
<Login />
</Route>
</Switch>
</div>
)
}
export default App