# React Router(V6) [Tutorial v6.8.1 | React Router](https://reactrouter.com/en/main/start/tutorial) > v6不兼容 v5, 变化较大 ```sh # 安装最新版v6 pnpm add react-router-dom ``` ## helloRouter ```jsx /** * react router 使用步骤 * 1. 安装react-router-dom包 * 2. 在main.jsx 中引入BrowserRouter组件 * 3. 将BrowserRouter设置为根组件 * 4. 在App.jsx 中引入 Routes, Route 组件 * 5. 用 Routes组件包裹Route组件 */ ``` ```jsx /** * Routes v6新增的组件 * 类似v5的Switch, 都是用于Route的容器 * Routes中的Route只有一个会被匹配 不用加exact了 * v6中 component render children 都不能用了 * 改为element指定要挂载的组件 */ ``` ```jsx // @/main.jsx import React from 'react' import ReactDOM from 'react-dom/client' import App from './App' import {BrowserRouter as Router} from 'react-router-dom' ReactDOM.createRoot(document.getElementById('root')).render( ) ``` ```jsx // @/App.jsx import { Routes, Route } from 'react-router-dom' import Menu from './components/Menu' import Home from './components/Home' import About from './components/About' function App() { return (
} /> } />
) } export default App ``` ```jsx // @/components/Home.jsx const Home = ()=>{ return (

主页

) } export default Home ``` ```jsx // @/components/About.jsx const About = ()=>{ return (

关于我们

) } export default About ``` ```jsx // @/components/Menu.jsx import { Link } from 'react-router-dom' const Menu = () => { return (
) } export default Menu ``` ## 钩子 ```jsx // useParams() 不变 // useLocation() 不变 // [x] useRouteMatch() 没有了 // useMatch(path) 检查当前url是否匹配某个路由,需要传参, 例如 useMatch('/about'),不匹配返回null, 匹配返回对象 // [x] useHistory() 没有了 // useNavigage() 获取一个用来跳转的函数 // ... import {useNavigate} from 'react-router-dom' // ... const nav = useNavigate() const clickHandler = ()=>{ nav('/about') // 默认使用push跳转,有历史记录 nav('/about',{replace:true}) // 使用replace跳转 } ``` ## 嵌套路由+ Outlet ```jsx /** * V6默认严格匹配,想取消,可以 path='/about/*' * Outlet 用来表示嵌套路由中的组件 * 当路径匹配成功, Outlet表示嵌套路由中的组件 * 当匹配失败, Outlet相当于不存在 * 有点像vue的插槽 */ ``` ```jsx // @/App.jsx // Route嵌套Route // '/about'可以省略成'about', '/about/hello'省略成'hello' import { Routes, Route } from 'react-router-dom' import Menu from './components/Menu' import Home from './components/Home' import About from './components/About' import Hello from './components/Hello' import Word from './components/Word' function App() { return (
} /> } > } /> } />
) } export default App ``` ```jsx // @/components/About // 添加Outlet组件 // 会智能匹配 hello组件或者word组件 import { Outlet } from 'react-router-dom' const About = ()=>{ return (

关于我们

) } export default About ``` ## Navigate组件 > V5使用 Redirect 重定向, V6使用 Navigate 组件 ```jsx // 默认使用push跳转 {!isLogin && } // 添加replace使用replace跳转 {!isLogin && } // 传递参数 {!isLogin && } // 在跳转后的页面用useLocation()可以拿到 ``` ## NavLink组件 > V5的 activeStyle activeClassName 取消了 > V6 改成style={()=>{}} 1. 使用style ```jsx { return isActive ? { backgroundColor: 'yellow' } : null }}> about/word ``` 2. 使用className ```jsx import classes from './Menu.module.css' // ... { return isActive ? classes.active : '' }}> about/hello ``` ```css /* Menu.module.css */ a.active { background-color: green; } ``` ## 高阶组件实现路由守卫 ```jsx // 没有登录访问权限页面,跳转登录页面 : } /> ``` 提取成组件 ```jsx import { useSelector } from 'react-redux' import { Navigate } from 'react-router-dom' const NeedAuth = props => { const { isLogin } = useSelector(state => state.auth) return isLogin ? props.children : } export default NeedAuth ``` ```jsx } /> ``` 想登录成功后返回原来的页面, 使用 useLocation 和 Navigate state 来传递和获取 path ```jsx import { useSelector } from 'react-redux' import { Navigate,useLocation } from 'react-router-dom' const NeedAuth = props => { const location = useLocation() const { isLogin } = useSelector(state => state.auth) return isLogin ? props.children : } export default NeedAuth ```