默认安装:
npm i react-router-dom
package.json
首先 入口js文件和<App/>外部还是要包裹 BrowserRouter 或者 HashRouter
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {BrowserRouter} from 'react-router-dom'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
一些组件的变化
6版本变化不大 加上end属性表示 子路由匹配上了 自身会失去高亮
利用函数判断是否 激活 没激活为空 false 就返回默认样式名 激活了就携带 新的样式名替换
<script>
function computedClassName({isActive}){
return isActive ? 'list-group-item wsg' : 'list-group-item'
}
</script>
<NavLink className={computedClassName} to='/about' >About</NavLink>
<NavLink className={computedClassName} to='/home' end>Home</NavLink>
router5 中 Route 外部使用 Swicth 来实现 单一匹配提高效率(非必须)Redirect实现默认定向 使用 component 标识显示哪个组件
6版本中 Route 外部必须被Routes包含 caseSensitive属性标识匹配时区分大小写 跳转方式默认为push replace = {true} 时为replace 标识显示哪个组件使用 element 重定向是使用Navigate再次跳转
<Routes>
<Route path='/about' caseSensitive replace={false} element={<About></About>}></Route>
<Route path='/home' caseSensitive replace={true} element={<Index></Index>}></Route>
<Route path='/' element={<Navigate to={'/about'}></Navigate>}></Route>
</Routes>
路由表
5版本是在当前组件配置 导航区写路径 下面写匹配的组件
6版本有统一的路由表 实际使用只要写跳转的路径 需要展示哪些组件路由表来确定 只需使用 Outlet 组件 占位即可
router/index.js
import {Navigate} from 'react-router-dom';
import Index from "../pages/Index";
import About from "../pages/About";
import News from '../pages/News';
import Message from '../pages/Message';
import Detail from '../pages/Detail'
import Detail2 from '../pages/Detail2'
import SearchQuery from '../pages/SearchQuery'
import Detail3 from '../pages/Detail3';
const router= [
{
path:'/about',
element:<About></About>
},
{
path:'/home',
element:<Index></Index>,
children:[
{
path:'news',
element:<News></News>,
children:[
{
path:'detail3',
element:<Detail3></Detail3>
}
]
},
{
path:'message',
element:<Message></Message>,
children:[
{
path:'detail/:id/:title/:content',
element:<Detail></Detail>
}
]
},
{
path:'SearchQuery',
element:<SearchQuery></SearchQuery>,
children:[
{
path:'detail',
element:<Detail2></Detail2>
}
]
},
{
path:'/home',
element:<Navigate to='/home/news'></Navigate>
}
]
},
{
path:'/',
element:<Navigate to='/about'></Navigate>
}
]
export default router
路由表中还可以配置嵌套子路由 以及路由占位符
传递params参数:
import React,{useState} from 'react'
import {Link,Outlet} from 'react-router-dom'
export default function Message() {
const [messages] = useState([
{id:'001',title:'LPL冠军',content:'JDG'},
{id:'002',title:'虚空冠军',content:'TES'},
{id:'003',title:'S11冠军',content:'EDG'},
{id:'004',title:'MSI冠军',content:'RNG'}
])
return (
<div>
这是基础params 路由传参
<ul>
{
messages.map(x =>{
return (
<li key={x.id}>
<Link to={`detail/${x.id}/${x.title}/${x.content}`}>{x.title}</Link>
</li>
)
})
}
</ul>
<Outlet></Outlet>
</div>
)
}
Detail.jsx
import React from 'react'
import {useParams} from 'react-router-dom'
export default function Detail() {
const {id,title,content} = useParams()
// const x = useMatch('/home/message/detail/:id/:title/:content')
return (
<ul>
<li>消息编号:{id}</li>
<li>消息标题:{title}</li>
<li>消息内容:{content}</li>
</ul>
)
}
传递search参数
import React,{useState} from 'react'
import {Link,Outlet} from 'react-router-dom'
export default function SearchQuery() {
const [SearchQuery] = useState([
{id:'001',title:'LPL冠军',content:'JDG'},
{id:'002',title:'虚空冠军',content:'TES'},
{id:'003',title:'S11冠军',content:'EDG'},
{id:'004',title:'MSI冠军',content:'RNG'}
])
return (
<div>
这是基础SearchQuery 路由传参
<ul>
{
SearchQuery.map(x =>{
return (
<li key={x.id}>
<Link to={`detail?id=${x.id}&title=${x.title}&content=${x.content}`}>{x.title}</Link>
</li>
)
})
}
</ul>
<Outlet></Outlet>
</div>
)
}
Detail2.jsx
import React from 'react'
import {useSearchParams} from 'react-router-dom'
export default function Detail2() {
const [search,setSearch] = useSearchParams()
const id = search.get('id')
const title = search.get('title')
const content = search.get('content')
// const x = useLoaction()
return (
<ul>
<button onClick={() => setSearch('id=008&title=捡灯笼&content=捞比')}>点击set SearchParam</button>
<li>消息编号:{id}</li>
<li>消息标题:{title}</li>
<li>消息内容:{content}</li>
</ul>
)
}
传递state参数
包含了 编程式导航用法 和其他的一些API
useInRouterContext()
组件是不是在 路由的上下文中 返回 布尔值 true false
useNavigationType()
返回用户是怎么来到当前页面的
pop push replace
pop 直接输入url 或者刷新页面
useOutLet()
呈现当前组件中要渲染的嵌套路由
const result = useOutLet()
console.log(reslut)
如果嵌套路由没有被挂载,则result 为null
如果嵌套路由已挂载 则展示嵌套的路由对象
useResolvedPath()
给定一个URL值 解析其中的 path search hash 值
import React,{useState} from 'react'
import {Link,Outlet,useNavigate,useInRouterContext,useNavigationType,useOutlet,useResolvedPath} from 'react-router-dom'
export default function SearchQuery() {
const navigate = useNavigate()
function jump(){
navigate('/home/SearchQuery/detail?id=120&title=信息管理&content=高薪')
}
const [lstate] = useState([
{id:'001',title:'LPL冠军',content:'JDG'},
{id:'002',title:'虚空冠军',content:'TES'},
{id:'003',title:'S11冠军',content:'EDG'},
{id:'004',title:'MSI冠军',content:'RNG'}
])
function gogo2(x){
navigate('detail3',{
replace:false,
state:{
id:x.id,
title:x.title,
content:x.content
}
})
}
console.log(useInRouterContext())
console.log(useNavigationType())
console.log(useOutlet())
console.log(useResolvedPath('/home/SearchQuery/detail?id=003&title=S11冠军&content=EDG#RF9'))
return (
<div>
这是Loaction.state 传参 在url 里不显示
<ul>
{
lstate.map(x =>{
return (
<li key={x.id}>
<Link to='detail3' state={
{
id:x.id,title:x.title,content:x.content
}}>{x.title}</Link>
<button onClick={() =>gogo2(x)}>{x.title}</button>
</li>
)
})
}
</ul>
<Outlet></Outlet>
编程式路由导航: <br />
<button onClick={jump}>点击跳转</button>
</div>
)
}
Detail3.jsx
import React from 'react'
import {useLocation} from 'react-router-dom'
export default function Detail3() {
const {state:{id,title,content}} = useLocation()
// const x = useLoaction()
return (
<ul>
<li>消息编号:{id}</li>
<li>消息标题:{title}</li>
<li>消息内容:{content}</li>
</ul>
)
}