最新的react-router-dom v6 完全不同于之前的版本。v5版本中路由组件和一般组件所接受的props有很大区别,而在v6中路由组件接受的props没有和v5一样拥有三个固定的属性,同时他们的写法也有了很大的区别。下面我讲述几个我当前遇见的写法
路由的基本使用
<Routes>
<Route path="/about" element={<About />} />
<Route path="/home" element={<Home />} />
<Route path="*" element={<Navigate to="/About" />} />
</Routes>
在v-6 中是把Switch标签替换成了Routes标签如果使用了Router就必须使用Routes component替换成了element,element的组件形式也是引用普通组件的形式。而不是v-5的 component={About}。
在v-5中通过设置Redirect当注册路由没有成功匹配时给予匹配项。也在v-6中弃用。
而是通过上面所示通过Navigate 来实现。
这里再提一点v-5中注册路由有先后顺序,匹配路径来渲染匹配成功的组件,按照顺序向下匹配而在v-6中不分先后。同时路由连接所给的路劲在v-5中只要给的路劲包含了注册路由的路劲就可以匹配,也就是可以进行模糊查询,而到了v-6将不再适用。
Navlink
路由的封装在v-6并没有变化,而<Navlink>删除了 activeClassName 样式,如果想自己给它设置想要的highligh样式可以通过style属性修改actived的状态通过箭头函数接收到isActive参数值style接收一个css样式数据返回值进行修改<NavLink> active状态样式。
< NavLink
style={({ isActive }) =>
isActive
? {
zIndex: 2,
color: "#fff",
backgroundColor: "rgb(247 151 60)",
borderColor: "rgb(247 151 60)",
}
: null
}
className="list-group-item"
{...this.props}
/>
也可以通过className属性来修改active状态通过接收到isActive参数值,最后className接收一个string返回值
<NavLink
className={({ isActive }) =>
"list-group-item" + (isActive ? " atnavl" : " ")
}
/>
嵌套路由
父组件的路由是先一步注册的,当我们在子组件注册路由,结合第一段的代码和以下代码,当我们点击home时我们就会匹配相应的路由,而找到了home组件 react会去寻找news和message 这一部分是v-5 的匹配路径前缀,只要没有开启严格模式就可以通过这种方式完成。
import React, { Component } from 'react'
import MyNavLink from '../MyNavLink'
import { Route, Routes } from 'react-router-dom'
import News from './News'
import Message from './Message'
export default class Home extends Component {
render() {
return (
<div>
<h3>我是Home内容</h3>
<div>
<ul className="nav nav-tabs">
<li>
<MyNavLink to="/home/news">News</MyNavLink>
</li>
<li>
<MyNavLink to="/home/message">Message</MyNavLink>
</li>
</ul>
<Routes>
<Route path="/home/news" element={<News />} />
<Route path="/home/message" element={<Message />} />
</Routes>
</div>
</div>
)
}
}
但是到了v-6继续使用上述方法会出现页面无法显示子路由的组件,没有匹配到"/home"路径
在 v6 中,所有路由路径始终是完全匹配。父/根路径需要指定 * 通配符,以便它们现在可以进行"前缀"匹配,所以解决办法是加上通配符*
<Route path="/*" element={<Home />} />
路由组件的参数传递
类式的路由组件传递参数在v-6中无法直接实现一般来说需要通过一个函数式的组件来包裹类组件过于繁琐,推荐使用函数式组件直接使用hooks传参会比较简单。
因为无法直接得到
this.props,于是我使用的window.location来实现数据传递,和V-5的search参数的方式一致。但是该方法只是为了帮助理解,不可实际应用,window.location不能直接更改,并不会触发更新,在案例里必须刷新才可以更改页面。嵌套一个函数式组件的方式
更为合适。