前言
A user‑obsessed, standards‑focused, multi‑strategy router you can deploy anywhere.(官网)
React通过remix-run/react-router实现路由
下载依赖
1
| npm install react-router-dom@6
|
配置模式
Hash模式
src/index.js1 2 3 4 5 6 7 8 9 10
| import { ReactDOM } from "react-dom/client" import App from "./App" import { HashRouter } from "react-router-dom"
const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <HashRouter> <App /> </HashRouter> );
|
History模式
src/index.js1 2 3 4 5 6 7 8 9 10
| import { ReactDOM } from "react-dom/client" import App from "./App" import { BrowserRouter } from "react-router-dom"
const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <BrowserRouter> <App /> </BrowserRouter> );
|
配置路由
以组件的形式配置路由
src/components/Home.jsx1 2 3 4 5
| import React from "react"
class Home extends React.Component {}
export default Home;
|
path:匹配的路径
element:渲染的组件
src/App.jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import React from "react" import { Routes, Route } from "react-router-dom" import Home from "./components/Home"
class App extends React.Component { render() { return ( <> <header></header> <main> <Routes> <Route path="/home" element={<Home />} /> </Routes> </main> <footer></footer> </> ); } }
export default App;
|
通配符匹配
src/App.jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import React from "react" import { Routes, Route } from "react-router-dom" import Home from "./components/Home" import PageNotFound from "./components/Home"
class App extends React.Component { render() { return ( <> <header></header> <main> <Routes> <Route path="/*" element={<Home />} /> </Routes> </main> <footer></footer> </> ); } }
export default App;
|
动态路由
src/App.jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import React from "react" import { Routes, Route } from "react-router-dom" import Home from "./components/Home" import PageNotFound from "./components/Home"
class App extends React.Component { render() { return ( <> <header></header> <main> <Routes> <Route path="/home/:key" element={<Home />} /> </Routes> </main> <footer></footer> </> ); } }
export default App;
|
以配置的形式配置路由
src/components/Home.jsx1 2 3 4 5
| import React from "react"
class Home extends React.Component {}
export default Home;
|
src/router/index.js1 2 3 4 5 6 7 8 9 10
| import Home from "../components/Home"
const routes = [ { path: "/home", element: <Home />, }, ];
export default routes;
|
src/App.jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import React from "react" import { useRoutes } from "react-router-dom" import routes from "./router"
class App extends React.Component { render() { return ( <> <header></header> <main> { useRoutes(routes) } </main> <footer></footer> </> ); } }
export default App;
|
跳转路由
通过组件跳转路由
Link组件
to:跳转的路径
replace:是否是Replace操作
false:缺省值,Push操作,可以返回
true:Replace操作,不可以返回
reloadDocument:是否刷新页面
false:缺省值,不刷新页面
true:刷新页面
src/components/Component.jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import React from "react" import { Link } from "react-router-dom"
class Component extends React.Component { render() { return ( <> <Link to="/home">首页</Link> </> ); } }
export default App;
|
1 2 3
| <div class="nav"> <a href="/home">首页</a> </div>
|
NavLink组件
src/components/Component.jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import React from "react" import { NavLink } from "react-router-dom"
class Component extends React.Component { render() { return ( <> <NavLink to="/home">首页</Link> </> ); } }
export default App;
|
1 2 3
| <div class="nav"> <a class="active" href="/home">首页</a> </div>
|
直接定义active类的样式
src/components/Component.jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import React from "react" import { NavLink } from "react-router-dom"
class Component extends React.Component { render() { return ( <> <NavLink to="/home" style={(param) => ({ color: param.isActive ? "red" : "" })}>首页</Link> </> ); } }
export default App;
|
自定义class名
src/components/Component.jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import React from "react" import { NavLink } from "react-router-dom"
class Component extends React.Component { render() { return ( <> <NavLink to="/home" className={(param) => param.isActive ? "active" : "" }>首页</Link> </> ); } }
export default App;
|
Navigate重定向组件
- 只要出现
<Navigate />立即重定向到指定页面
src/components/Component.jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import React from "react" import { Navigate } from "react-router-dom"
class Component extends React.Component { render() { return ( <> <Navigate to="/home" /> </> ); } }
export default App;
|
src/components/Home.jsx1 2 3 4 5
| import React from "react"
class Home extends React.Component {}
export default Home;
|
src/App.jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import React from "react" import { Routes, Route } from "react-router-dom" import Home from "./components/Home"
class App extends React.Component { render() { return ( <> <header></header> <main> <Routes> <Route path="/" element={<Navigate to="/home" />} /> <Route path="/home" element={<Home />} /> </Routes> </main> <footer></footer> </> ); } }
export default App;
|
通过JS跳转路由
函数式组件
src/components/Component.jsx1 2 3 4 5 6 7 8 9 10 11 12 13
| import { useNavigate } from "react-router-dom"
function Component(props) { const navigate = useNavigate();
return ( <> <button onClick={() => navigate("/home")}>首页</button> </> ); }
export default Component;
|
配置是否是Replace操作
replace:是否是Replace操作
false:缺省值,Push操作,可以返回
true:Replace操作,不可以返回
src/components/Component.jsx1 2 3 4 5 6 7 8 9 10 11 12 13
| import { useNavigate } from "react-router-dom"
function Component(props) { const navigate = useNavigate();
return ( <> <button onClick={() => navigate("/home", { replace: false })}>首页</button> </> ); }
export default Component;
|
通过跳转层级跳转
-1:正数表示前进次数,负数表示后退次数
src/components/Component.jsx1 2 3 4 5 6 7 8 9 10 11 12 13
| import { useNavigate } from "react-router-dom"
function Component(props) { const navigate = useNavigate();
return ( <> <button onClick={() => navigate(-1)}>首页</button> </> ); }
export default Component;
|
类组件
src/hoc/withRouter.jsx1 2 3 4 5 6 7 8 9 10
| import { useNavigate } from "react-router-dom"
function withRouter(WrapperComponent) { return function (props) { const navigate = useNavigate(); return <WrapperComponent { ...props } navigate={ navigate } />; } }
export default withRouter;
|
src/components/Component.jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import React from "react" import withRouter from "../hoc/withRouter"
class Component extends React.Component { render() { return ( <> <button onClick={() => this.props.navigate("/home")}>首页</button> </> ); } }
export default withRouter(Component);
|
二级路由
src/components/Son.jsx1 2 3 4 5
| import React from "react"
class Son extends React.Component {}
export default Son;
|
src/components/Daughter.jsx1 2 3 4 5
| import React from "react"
class Daughter extends React.Component {}
export default Daughter;
|
src/components/Father.jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import React from "react" import { Link, Outlet } from "react-router-dom"
class Father extends React.Component { render() { return ( <> <Link to="/father/son">子页面1</Link> <Link to="/father/daughter">子页面2</Link>
{/* 父组件中作为子组件的占位组件 */} <Outlet /> </> ); } }
export default Father;
|
配置路由
以组件的形式配置路由
src/App.jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import React from "react" import { Routes, Route } from "react-router-dom" import Father from "./components/Father" import Son from "./components/Son" import Daughter from "./components/Daughter"
class App extends React.Component { render() { return ( <> <header></header> <main> <Routes> <Route path="/father" element={<Father />}> <Route path="/father/son" element={<Son />} /> <Route path="/father/daughter" element={<Daughter />} /> </Route> </Routes> </main> <footer></footer> </> ); } }
export default App;
|
src/App.jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import React from "react" import { Routes, Route } from "react-router-dom" import Father from "./components/Father" import Son from "./components/Son" import Daughter from "./components/Daughter"
class App extends React.Component { render() { return ( <> <header></header> <main> <Routes> <Route path="/" element={<Navigate to="/father" />} /> <Route path="/father" element={<Father />}> <Route path="/father" element={<Navigate to="/father/son" />} /> <Route path="/father/son" element={<Son />} /> <Route path="/father/daughter" element={<Daughter />} /> </Route> </Routes> </main> <footer></footer> </> ); } }
export default App;
|
以配置的形式配置路由
src/router/index.js1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import Father from "../components/Father" import Son from "../components/Son" import Daughter from "../components/Daughter"
const routes = [ { path: "/father", element: <Father /> children: [ { path: "/father/son", element: <Son /> }, { path: "/father/daughter", element: <Daughter /> } ] } ];
export default routes;
|
src/App.jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import React from "react" import { useRoutes } from "react-router-dom" import routes from "./router"
class App extends React.Component { render() { return ( <> <header></header> <main> { useRoutes(routes) } </main> <footer></footer> </> ); } }
export default App;
|
获取参数
动态路由参数
request1
| GET http://127.0.0.1:80/home/value
|
配置动态路由
传送门
函数式组件
- 在函数式组件中,通过Hooks的形式获取动态路由参数
src/components/Component.jsx1 2 3 4 5 6 7 8 9 10 11 12 13
| import { useParams } from "react-router-dom"
function Component(props) { const params = useParams();
return ( <> { params.key } </> ); }
export default Component;
|
类组件
src/hoc/withRouter.jsx1 2 3 4 5 6 7 8 9 10
| import { useParams } from "react-router-dom"
function withRouter(WrapperComponent) { return function (props) { const params = useParams(); return <WrapperComponent { ...props } params={ params } />; } }
export default withRouter;
|
src/components/Component.jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import React from "react" import withRouter from "../hoc/withRouter"
class Component extends React.Component { render() { return ( <> { this.props.params.get("key", "default") } </> ); } }
export default withRouter(Component);
|
查询字符串
request1
| GET http://127.0.0.1:80/home?key=value
|
函数式组件
- 在函数式组件中,通过Hooks的形式获取动态路由参数
src/components/Component.jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import { useSearchParams } from "react-router-dom"
function Component(props) { const [ searchParams, setSearchParams ] = useSearchParams(); const searchParamsObject = Object.fromEntries(searchParams);
return ( <> { searchParamsObject.key } </> ); }
export default Component;
|
类组件
src/hoc/withRouter.jsx1 2 3 4 5 6 7 8 9 10 11
| import { useSearchParams } from "react-router-dom"
function withRouter(WrapperComponent) { return function (props) { const [ searchParams, setSearchParams ] = useSearchParams(); const searchParamsObject = Object.fromEntries(searchParams); return <WrapperComponent { ...props } searchParamsObject={ searchParamsObject } />; } }
export default withRouter;
|
src/components/Component.jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import React from "react" import withRouter from "../hoc/withRouter"
class Component extends React.Component { render() { return ( <> { this.props.searchParams.key } </> ); } }
export default withRouter(Component);
|
完成