目录:
- 课程说明
- 一级路由
- 重定向
- NavLink高亮
- useRoutes路由表
- 嵌套路由
- 路由的params参数
- 路由的search参数
- 路由的state参数
- 编程式路由导航
- useRouterContext
- useNavigationType
- useOutlet
- useResolvedPath()
- 总结
- 项目地址
1.课程说明
概述
- React Router以三个不同的包发布到npm 上,它们分别为:
- 1.react-router:路由的核心库,提供了很多的:组件、钩子。
- 2.react-router-dom:包含react-router所有内容,并添加一些专门用于DOM的组件,例如<BrowserRouter>等。
- 3. react-router-native:包括react-router所有内容,并添加一些专门用于ReactNative的API例如:<NativeRouter>等。
- 2.与React Router 5.x版本相比,改变了什么?
- 1.内置组件的变化:移除<Switch/>,新增<Routes/>等。
- ⒉.语法的变化: component={About]变为element={<About/>}等。
- 3.新增多个hook: useParams 、useNavigate 、useMatch 等。
- 4.官方明确推荐函数式组件了!!!
2.一级路由
About.jsx
import React from 'react';function About(props) {return (<div><h3>我是About的内容</h3></div>);
}export default About;
Home.jsx
import React from 'react';function Home(props) {return (<div><h3>我是Home的内容</h3></div>);
}export default Home;
App.js
import React from 'react';
import {NavLink, Routes, Route} from "react-router-dom";
import About from "./pages/About";
import Home from "./pages/Home";function App(props) {return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><div className="page-header"><h2>React Router Demo</h2></div></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><NavLink className="list-group-item" to="/about">About</NavLink><NavLink className="list-group-item" to="/home">Home</NavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body"><Routes><Route path="/about" element={<About></About>}></Route><Route path="/home" element={<Home></Home>}></Route></Routes></div></div></div></div></div>);
}export default App;
index.js
import React from 'react';
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>
);
3.重定向
App.js
import React from 'react';
import {NavLink, Routes, Route, Navigate} from "react-router-dom";
import About from "./pages/About";
import Home from "./pages/Home";function App(props) {return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><div className="page-header"><h2>React Router Demo</h2></div></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><NavLink className="list-group-item" to="/about">About</NavLink><NavLink className="list-group-item" to="/home">Home</NavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body"><Routes><Route path="/ABOUT" caseSensitive element={<About></About>}></Route><Route path="/home" element={<Home></Home>}></Route><Route path="/" element={<Navigate to="/about"/>}></Route></Routes></div></div></div></div></div>);
}export default App;
Home.jsx
import React, {useState} from 'react';
import {Navigate} from "react-router-dom";function Home(props) {const [sum, setSum] = useState(1)return (<div><h3>我是Home的内容</h3>{sum === 2 ? <Navigate to="/about/" replace={true}/> : <h4>当前sum的值是:{sum}</h4>}<button onClick={() => setSum(2)}>点我将sum变为2</button></div>);
}export default Home;
4.NavLink高亮
App.js
import React from 'react';
import {NavLink, Routes, Route, Navigate} from "react-router-dom";
import About from "./pages/About";
import Home from "./pages/Home";function App(props) {function computedClassName({isActive}) {return isActive ? 'list-group-item atguigu' : 'list-group-item'}return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><div className="page-header"><h2>React Router Demo</h2></div></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><NavLink className={computedClassName} to="/about">About</NavLink><NavLink className={computedClassName} to="/home">Home</NavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body"><Routes><Route path="/about" element={<About></About>}></Route><Route path="/home" element={<Home></Home>}></Route><Route path="/" element={<Navigate to="/about"/>}></Route></Routes></div></div></div></div></div>);
}export default App;
About.jsx
import React from 'react';function About(props) {return (<div><h3>我是About的内容</h3></div>);
}export default About;
Home.jsx
import React from 'react';function Home(props) {return (<div><h3>我是Home的内容</h3></div>);
}export default Home;
5.useRoutes路由表
route/index.js
import About from "../pages/About";
import Home from "../pages/Home";
import {Navigate} from "react-router-dom";export default [{path: '/about',element: <About></About>},{path: '/home',element: <Home></Home>},{path: '/',element: <Navigate to="/about"></Navigate>},
]
App.js
import React from 'react';
import {NavLink, useRoutes} from "react-router-dom";
import routes from "./routes";function App(props) {const element = useRoutes(routes)return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><div className="page-header"><h2>React Router Demo</h2></div></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><NavLink className="list-group-item" to="/about">About</NavLink><NavLink className="list-group-item" to="/home">Home</NavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body">{/*<Routes>*/}{/* <Route path="/about" element={<About></About>}></Route>*/}{/* <Route path="/home" element={<Home></Home>}></Route>*/}{/* <Route path="/" element={<Navigate to="/about"/>}></Route>*/}{/*</Routes>*/}{element}</div></div></div></div></div>);
}export default App;
6.嵌套路由
App.js
import React from 'react';
import {NavLink, useRoutes} from "react-router-dom";
import routes from "./routes";function App(props) {const element = useRoutes(routes)return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><div className="page-header"><h2>React Router Demo</h2></div></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><NavLink className="list-group-item" to="/about">About</NavLink><NavLink className="list-group-item" end to="/home">Home</NavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body">{/*<Routes>*/}{/* <Route path="/about" element={<About></About>}></Route>*/}{/* <Route path="/home" element={<Home></Home>}></Route>*/}{/* <Route path="/" element={<Navigate to="/about"/>}></Route>*/}{/*</Routes>*/}{element}</div></div></div></div></div>);
}export default App;
route/index.js
import About from "../pages/About";
import Home from "../pages/Home";
import {Navigate} from "react-router-dom";
import News from "../pages/News";
import Message from "../pages/Message";export default [{path: '/about',element: <About></About>},{path: '/home',element: <Home></Home>,children: [{path: 'news',element: <News></News>},{path: 'message',element: <Message></Message>}]},{path: '/',element: <Navigate to="/about"></Navigate>},
]
News.jsx
import React from 'react';function News(props) {return (<div><ul><li>news001</li><li>news002</li><li>news003</li></ul></div>);
}export default News;
Message.jsx
import React from 'react';function Message(props) {return (<div><ul><li><a href="/message1">message001</a> </li><li><a href="/message2">message002</a> </li><li><a href="/message/3">message003</a> </li></ul></div>);
}export default Message;
Home.jsx
import React from 'react';
import {NavLink, Outlet} from "react-router-dom";function Home(props) {return (<div><h2>Home组件内容</h2><div><ul className="nav nav-tabs"><li><NavLink className="list-group-item" to="news">News</NavLink>{/*<NavLink className="list-group-item" to="./news">News</NavLink>*/}{/*<NavLink className="list-group-item" to="/home/news">News</NavLink>*/}</li><li><NavLink className="list-group-item " to="message">Message</NavLink>{/*<NavLink className="list-group-item " to="./message">Message</NavLink>*/}{/*<NavLink className="list-group-item " to="/home/message">Message</NavLink>*/}</li></ul><Outlet></Outlet></div></div>);
}export default Home;
About.jsx
import React from 'react';function About(props) {return (<div><h3>我是About的内容</h3></div>);
}export default About;
7.路由的params参数
Detail.jsx
import React from 'react';
import {useMatch, useParams} from "react-router-dom";function Detail(props) {const {id, title, content} = useParams()const x = useMatch('/home/message/detail/:id/:title/:content')console.log(x)return (<div><ul><li>消息编号:{id}</li><li>消息标题:{title}</li><li>消息内容:{content}</li></ul></div>);
}export default Detail;
Message.jsx
import React, {useState} from 'react';
import {Link, Outlet} from "react-router-dom";function Message(props) {const [messages] = useState([{id: '001', title: '消息1', content: '锄禾日当午'},{id: '002', title: '消息2', content: '汗滴禾下土'},{id: '003', title: '消息3', content: '谁知盘中餐'},{id: '004', title: '消息4', content: '粒粒皆辛苦'},])return (<div><ul>{messages.map((m) => {return (<li key={m.id}><Link to={`detail/${m.id}/${m.title}/${m.content}`}>{m.title}</Link> </li>)})}</ul><hr></hr><Outlet></Outlet></div>);
}export default Message;
routes/index.js
import About from "../pages/About";
import Home from "../pages/Home";
import {Navigate} from "react-router-dom";
import News from "../pages/News";
import Message from "../pages/Message";
import Detail from "../pages/Detail";export default [{path: '/about',element: <About></About>},{path: '/home',element: <Home></Home>,children: [{path: 'news',element: <News></News>},{path: 'message',element: <Message></Message>,children: [{path: 'detail/:id/:title/:content',element: <Detail></Detail>}]}]},{path: '/',element: <Navigate to="/about"></Navigate>},
]
8.路由的search参数
Detail.jsx
import React from 'react';
import {useLocation, useSearchParams} from "react-router-dom";function Detail(props) {const [search, setSearch] = useSearchParams()const id = search.get('id')const title = search.get('title')const content = search.get('content')const x = useLocation()console.log(x)return (<div><ul><li><button onClick={() => setSearch('id=008&title=哈哈&content=嘻嘻')}>点我更新一下收到的search参数</button></li><li>消息编号:{id}</li><li>消息标题:{title}</li><li>消息内容:{content}</li></ul></div>);
}export default Detail;
Message.jsx
import React, {useState} from 'react';
import {Link, Outlet} from "react-router-dom";function Message(props) {const [messages] = useState([{id: '001', title: '消息1', content: '锄禾日当午'},{id: '002', title: '消息2', content: '汗滴禾下土'},{id: '003', title: '消息3', content: '谁知盘中餐'},{id: '004', title: '消息4', content: '粒粒皆辛苦'},])return (<div><ul>{messages.map((m) => {return (<li key={m.id}>{/*<Link to={`detail/${m.id}/${m.title}/${m.content}`}>{m.title}</Link> */}<Link to={`detail?id=${m.id}&title=${m.title}&content=${m.content}`}>{m.title}</Link> </li>)})}</ul><hr></hr><Outlet></Outlet></div>);
}export default Message;
index.js
import About from "../pages/About";
import Home from "../pages/Home";
import {Navigate} from "react-router-dom";
import News from "../pages/News";
import Message from "../pages/Message";
import Detail from "../pages/Detail";export default [{path: '/about',element: <About></About>},{path: '/home',element: <Home></Home>,children: [{path: 'news',element: <News></News>},{path: 'message',element: <Message></Message>,children: [{path: 'detail',element: <Detail></Detail>}]}]},{path: '/',element: <Navigate to="/about"></Navigate>},
]
9.路由的state参数
Detail.jsx
import React from 'react';
import {useLocation} from "react-router-dom";function Detail(props) {const {state: {id, title, content}} = useLocation()return (<div><ul><li>消息编号:{id}</li><li>消息标题:{title}</li><li>消息内容:{content}</li></ul></div>);
}export default Detail;
Message.jsx
import React, {useState} from 'react';
import {Link, Outlet} from "react-router-dom";function Message(props) {const [messages] = useState([{id: '001', title: '消息1', content: '锄禾日当午'},{id: '002', title: '消息2', content: '汗滴禾下土'},{id: '003', title: '消息3', content: '谁知盘中餐'},{id: '004', title: '消息4', content: '粒粒皆辛苦'},])return (<div><ul>{messages.map((m) => {return (<li key={m.id}>{/*<Link to={`detail/${m.id}/${m.title}/${m.content}`}>{m.title}</Link> */}{/*<Link to={`detail?id=${m.id}&title=${m.title}&content=${m.content}`}>{m.title}</Link>*/}<Link to="detail"state={{id: m.id, title: m.title, content: m.content}}>{m.title}</Link> </li>)})}</ul><hr></hr><Outlet></Outlet></div>);
}export default Message;
routes/index.js
import About from "../pages/About";
import Home from "../pages/Home";
import {Navigate} from "react-router-dom";
import News from "../pages/News";
import Message from "../pages/Message";
import Detail from "../pages/Detail";export default [{path: '/about',element: <About></About>},{path: '/home',element: <Home></Home>,children: [{path: 'news',element: <News></News>},{path: 'message',element: <Message></Message>,children: [{path: 'detail',element: <Detail></Detail>}]}]},{path: '/',element: <Navigate to="/about"></Navigate>},
]
10.编程式路由导航
Header.jsx
import React from 'react';
import {useNavigate} from "react-router-dom";function Header(props) {const navigate = useNavigate()function back() {navigate(-1)}function forward() {navigate(1)}return (<div><div className="col-xs-offset-2 col-xs-8"><div className="page-header"><h2>React Router Demo</h2><button onClick={back}>后退</button><button onClick={forward}>前进</button></div></div></div>);
}export default Header;
Message.jsx
import React, {useState} from 'react';
import {Link, Outlet, useNavigate} from "react-router-dom";function Message(props) {const [messages] = useState([{id: '001', title: '消息1', content: '锄禾日当午'},{id: '002', title: '消息2', content: '汗滴禾下土'},{id: '003', title: '消息3', content: '谁知盘中餐'},{id: '004', title: '消息4', content: '粒粒皆辛苦'},])const navigate = useNavigate()function showDetail(m) {navigate('detail', {replace: false, state: {id: m.id, title: m.title, content: m.content}})}return (<div><ul>{messages.map((m) => {return (<li key={m.id}>{/*<Link to={`detail/${m.id}/${m.title}/${m.content}`}>{m.title}</Link> */}{/*<Link to={`detail?id=${m.id}&title=${m.title}&content=${m.content}`}>{m.title}</Link>*/}<Link to="detail"state={{id: m.id, title: m.title, content: m.content}}>{m.title}</Link><button onClick={() => showDetail(m)}>查看详情</button></li>)})}</ul><hr></hr><Outlet></Outlet></div>);
}export default Message;
App.js
import React from 'react';
import {NavLink, useRoutes} from "react-router-dom";
import routes from "./routes";
import Header from "./components/Header";function App(props) {const element = useRoutes(routes)return (<div><div className="row"><Header></Header></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><NavLink className="list-group-item" to="/about">About</NavLink><NavLink className="list-group-item" to="/home">Home</NavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body">{/*<Routes>*/}{/* <Route path="/about" element={<About></About>}></Route>*/}{/* <Route path="/home" element={<Home></Home>}></Route>*/}{/* <Route path="/" element={<Navigate to="/about"/>}></Route>*/}{/*</Routes>*/}{element}</div></div></div></div></div>);
}export default App;
11.useRouterContext
- uselnRouterContext()
- 作用:如果组件在<Router>的上下文中呈现,则useInRouterContext钩子返回true,否则返回false。
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import {BrowserRouter} from "react-router-dom";
import Demo from "./components/Demo";const root = ReactDOM.createRoot(document.getElementById('root'));root.render(<Demo></Demo>,<BrowserRouter><App/></BrowserRouter>
);
App.js
import React from 'react';
import {NavLink, useInRouterContext, useRoutes} from "react-router-dom";
import routes from "./routes";
import Header from "./components/Header";function App(props) {const element = useRoutes(routes)console.log('@',useInRouterContext())return (<div><div className="row"><Header></Header></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><NavLink className="list-group-item" to="/about">About</NavLink><NavLink className="list-group-item" to="/home">Home</NavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body">{/*<Routes>*/}{/* <Route path="/about" element={<About></About>}></Route>*/}{/* <Route path="/home" element={<Home></Home>}></Route>*/}{/* <Route path="/" element={<Navigate to="/about"/>}></Route>*/}{/*</Routes>*/}{element}</div></div></div></div></div>);
}export default App;
Demo.jsx
import React from 'react';
import {useInRouterContext} from "react-router-dom";function Demo(props) {console.log(useInRouterContext())return (<div>demo</div>);
}export default Demo;
Header.jsx
import React from 'react';
import {useInRouterContext, useNavigate} from "react-router-dom";function Header(props) {const navigate = useNavigate()console.log(useInRouterContext())function back() {navigate(-1)}function forward() {navigate(1)}return (<div><div className="col-xs-offset-2 col-xs-8"><div className="page-header"><h2>React Router Demo</h2><button onClick={back}>后退</button><button onClick={forward}>前进</button></div></div></div>);
}export default Header;
12.useNavigationType
- useNavigationType()
- 作用:返回当前的导航类型((用户是如何来到当前页面的)。
- 返回值:POP、PUSH、REPLACE]。
- 备注:PoP是指在浏览器中直接打开了这个路由组件(刷新页面)。
News.jsx
import React from 'react';
import {useNavigationType} from "react-router-dom";function News(props) {console.log(useNavigationType())return (<div><ul><li>news001</li><li>news002</li><li>news003</li></ul></div>);
}export default News;
13.useOutlet
- useOutlet()
- 作用:用来呈现当前组件中要渲染的嵌套路由。
- 示例代码:
const result = useoutlet( )
console.log( result)
//如果嵌套路由没有挂载,则result为null
//如果嵌套路由已经挂载,则展示嵌套的路由对象
Home.jsx
import React from 'react';
import {NavLink, Outlet, useOutlet} from "react-router-dom";function Home(props) {console.log(useOutlet())return (<div><h2>Home组件内容</h2><div><ul className="nav nav-tabs"><li><NavLink className="list-group-item" to="news">News</NavLink></li><li><NavLink className="list-group-item " to="message">Message</NavLink></li></ul><Outlet></Outlet></div></div>);
}export default Home;
14.useResolvedPath()
- useResolvedPath()
- 作用:给定一个URL值,解析其中的: path、search、hash值。
News.jsx
import React from 'react';
import {useResolvedPath} from "react-router-dom";function News(props) {console.log(useResolvedPath('/user?id=001&name=tom#qwe'))return (<div><ul><li>news001</li><li>news002</li><li>news003</li></ul></div>);
}export default News;
15.总结:
2.Component
1. <BrowserRouter>
- 说明:<BrowserRouter>用于包裹整个应用。
- 示例代码:
-
import React from "react"; import ReactDOM from "react-dom" ; import { BrowserRouter } from "react-router-dom" ;ReactDOM.render( <BrowserRouter> {/*整体结构(通常为App组件)*/} </BrowserRouter> ,root );
2.<HashRouter>
- 说明:作用与<BrowserRouter>一样,但<HashRouter>修改的是地址栏的hash值。
- 备注:6.x版本中<HashRouter>、<BrowserRouter>的用法与5.x相同。
3.<Routes/> 与<Route/>
- v6版本中移出了先前的<Switch>,引入了新的替代者:<Routes>。
- <Routes>和<Route>要配合使用,且必须要用<Routes>包裹<Route>。
- <Route>相当于一个if语句,如果其路径与当前URL匹配,则呈现其对应的组件。
- <Route caseSensitive>属性用于指定:匹配时是否区分大小写(默认为false)。
- 当URL发生变化时,<Routes>都会查看其所有子<Route>元素以找到最佳匹配并呈现组件。
- <cRoute也可以嵌套使用,且可配合useRoutes()配置“路由表”,但需要通过<outlet>组件来渲染其子路由。
- 示例代码:
4.<Link>
- 作用:修改URL,且不发送网络请求(路由链接)。
5.<NavLink>
- 作用:与<Link>组件类似,且可实现导航的“高亮"效果。
- 示例代码:
6.<Navigate>
- 作用:只要<Navigate>组件被渲染,就会修改路径,切换视图。
- replace属性用于控制跳转模式(push或 replace,默认是push) 。
- 示例代码:
7. <outlet>
- 当<Route>产生嵌套时,渲染其对应的后续子路由。
3.Hooks
1.useRoutes()
- 作用:根据路由表,动态创建<Routes>和<Route> 。
2.useNavigate
- 作用:返回一个函数用来实现编程式导航。
- 示例代码:
3. useParams()
- 作用:回当前匹配路由的params参数,类似于5.x中的match.params .
- 示例代码:
4.useSearchParams()
- 作用:用于读取和修改当前位置的URL中的查询字符串。
- 返回一个包含两个值的数组,内容分别为:当前的seaech参数、更新search的函数。
- 示例代码:
5.useLocation()
- 作用:获取当前location信息,对标5.x中的路由组件的location属性。
- 示例代码:
6.useMatch()
- 作用:返回当前匹配信息,对标5.x中的路由组件的match属性。
- 示例代码:
16.项目地址
https://gitee.com/coderPatrickStar/react/tree/master/20231003