react-router-dom6中常用的Hooks
react-router-dom6中常用的Hooks
上一篇文章中版本5中介绍了一些5和6的区别,这篇文章将继续介绍5和6的区别,版本6中新增了一些Hooks,这里介绍6版本中常用的几个Hooks
嵌套路由Hook-useRoutes
根据定义,嵌套路由就是组件里面套组件
在5中,在Home组件中写news和message组件,通常是这样写的:
import {NavLink} from 'react-router-dom'
function Home(){
return (
<div>
<ul>
<li><NavLink to="/news">News</NavLink></li>
<li><NavLink to="/message">Message</NavLink></li>
</ul>
<Switch>
<Route path='/home/news' component={About}/>
<Route path='/home/message' component={Home}/>
</Switch>
</div>
)
}
在6中,路由表的写法发生了一些变化,而且App组件中用element去注册路由表,Home组件中直接用Outlet去指定路由组件呈现的位置
路由表如下:
import {Navigate,useRoutes} from 'react-router-dom'
const element=useRoutes([
{
path:'/about',
element:<About/>
},
{
path:'/home',
element:<Home/>,
children:[
{
path:'news',
element:<News/>
},
{
path:'message',
element:<Message/>
}
]
},
{
path:'/',
element:<Navigate to="/about"/>
}
])
Home组件中写法如下:
import {NavLink,Outlet} from 'react-router-dom'
function Home(){
return (
<div>
<ul>
<li><NavLink to="news">News</NavLink></li>
<li><NavLink to="message">Message</NavLink></li>
</ul>
<Outlet/>
</div>
)
}
需要注意的是,这里有三个点不太一样,一个是路由表的写法发生了变化,引入了Outlet,同时NavLink的to的路由的写法也变简单了,不需要在子路由前面写父级路由了
路由的params传参Hook-useParams
之前5的版本的路由传参,是直接调用this.props,this.props上面的history、location以及match会带有传过来的参数,这里就不做赘述。
但是函数式的组件是没有this的,6版本对此进行了改进,删掉了history,这个时候就需要借助一个Hook:useParams
,这里就和5版本不太一样,5版本的路由表需要声明参数:
import {Navigate,useRoutes} from 'react-router-dom'
const element=useRoutes([
{
path:'/about',
element:<About/>
},
{
path:'/home',
element:<Home/>,
children:[
{
path:'news',
element:<News/>
},
{
path:'message',
element:<Message/>,
children:[
{
path:'detail/:id/:title/:content',
element:<Detail/>
}
]
}
]
},
{
path:'/',
element:<Navigate to="/about"/>
}
])
接收方可以这样写:
import {useParams} from 'react-router-dom'
function Detail(){
const {xxx}=useParams
}
路由的search参数Hook-useSearchParams
这个写法和5中类似,首先在Link
标签中占位,
<Link to='detail?id=xxx&title=xxx&content=xxx'></Link>
然后我们需要在Detail组件中接收这个参数:
import {useSearchParams} from 'react-router-dom'
function Detail(){
const {search,setSearch}=useSearchParams()
const id =search.get('id')
const title=search.get('title')
const content=search.get('context')
return (
<ul>
<li>
<button onClick={()=>setSearch('id=008&title=haha')}>点我更新一下search参数</button>
</li>
<li>编号:{id}</li>
<li>标题:{title}</li>
<li>内容:{content}</li>
</ul>
)
}
路由的state参数Hook-useLocation
和前面的类似,首先是在Link
标签中占位:
<Link to='detail' state={id:xxx,title:xxx,content:xxx}></Link>
然后我们需要在Detail组件中接收这个参数:
import {useLocation} from 'react-router-dom'
function Detail(){
const {state:{id,title,context}}=useLocation()
return (
<ul>
<li>编号:{id}</li>
<li>标题:{title}</li>
<li>内容:{content}</li>
</ul>
)
}
编程式路由导航Hook-useNavigate
在5当中,我们使用Link
、NavLink
进行链接的点击跳转,6中除了Link
、NavLink
之外,新增了Navigate
。
下面我们讨论这种情况,我们需要在组件的页面上写一个按钮button,当我们点击按钮的时候进行跳转,我们自然会想到按钮绑定事件,但是当我们在绑定的事件的函数中写Link
、NavLink
这些标签的时候,它是没办法渲染到页面中的,所以一般我们会引入一个hook
去写:
import {useNavigate} from 'react-router-dom'
function Message(){
const navigate=useNavigate()
function showDetail(){
//跳转到detail子路径中
navigate('detail',{
replace:false,
state:{
id:xxx
}
})
}
return(
<div>
<button onClick={showDetail}>点击我跳转</button>
</div>
)
}
useInRouterContext()
**作用:**如果组件在<Router>
的上下文中呈现,则useInRouterContext
钩子返回true,否则返回false
useNavigationType()
- 作用:返回当前的导航类型(用户是如何来到当前页面的)
- 返回值:
POP
、PUSH
、REPLACE
- 备注:
POP
是指在浏览器中直接打开了这个路由组件(刷新页面)
我们可以验证一下,首先在组件中引入:
import {useNavigationType} from 'react-router-dom'
console.log(useNavigationType())
这个时候我们会发现,当我们在定义链接的时候,如果设置路由组件跳转方式:
<NavLink to='news'></NavLink>
(默认情况,控制台输出为PUSH)<NavLink to='news' replace></NavLink>
(该情况控制台输出为REPLACE)- 点击刷新(控制台输出POP)
这就是整个react-router6与react-router5的一些比较常用的区别,还是推荐大家直接看官方文档,那里会写的更加详细