React-Router V6版本的升级了也有段时间了,部分同学还是对v6版本有一些地方不太理解,今天咱们花10分钟来讲下v5和v6有哪些使用上的差异。
React-Router V6版本常用路由组件和hooks
组件名 | 作用 | 说明 |
---|---|---|
|
一组路由 | 代替原有 ,所有子路由都用基础的Router children来表示 |
|
基础路由 | Router是可以嵌套的,解决原有V5中严格模式,后面与V5区别会详细介绍 |
|
导航组件 | 在实际页面中跳转使用 |
|
自适应渲染组件 | 根据实际路由url自动选择组件 |
hooks名 | 作用 | 说明 |
---|---|---|
useParams |
返回当前参数 | 根据路径读取参数 |
useNavigate |
返回当前路由 | 代替原有V5中的 useHistory |
useOutlet |
返回根据路由生成的element | |
useLocation |
返回当前的location 对象 | |
useRoutes |
同Routers组件一样,只不过是在js中使用 | |
useSearchParams |
用来匹配URL中?后面的搜索参数 |
如表格,V6版本常用的组件和hooks,这些是新增的常用部分,不常用部分可以查看官方文档。接下来,咱们通过案例的形式来比较上面新增的那些变化。
在app.js中分别搭建home和about页面路由。
v5的写法
import { HashRouter,Route,Switch } from 'react-router-dom'
......
v6的写法
import { HashRouter,Route,Routes } from 'react-router-dom'
......
//Routes替换了Switch
}>
}>
嵌套路由是V6版本对之前版本一个较大的升级,采用嵌套路由会智能的识别
......
}>
} />
} />
当访问 /user/123 的时候,组件树将会变成这样
<App>
<Users>
<UserDetail/>
Users>
App>
当访问/user/create的时候,组件树将变成这样
<App>
<Users>
<NewUser/>
Users>
App>
注意,上面写法需要在父组件中指定子组件渲染位置,
function Users() {
return (
Users
);
}
当然除了上面写法还有另一种写法
在App.js父组件中创建一级路由
.......
} />
}/>
然后在Home组件中配置二级路由
{/* 嵌套路由写法 这里可以省略/home一级路由 */}
}/>
}/>
v5写法
# 重定向 from从哪里来 to重定向到何处去
# 404设置 省略 path="*"
v6写法
import { Route,Routes,Navigate } from 'react-router-dom'
.......
{/* index属性来指定默认路由/ */}
} />
{/* 404 path="*"不能省略 */}
} />
由于v6版本已经废弃withRouter这个高阶函数,所以类组件获取路由对象可以通过封装高阶组件的方式来创建出来withRouter这个函数,代码如下
import {
useLocation,
useNavigate,
useParams
} from "react-router-dom";
//封装新的withRouter高阶函数
export function withRouter(Component) {
function ComponentWithRouterProp(props) {
let location = useLocation();
let navigate = useNavigate();
let params = useParams();
return (
);
}
return ComponentWithRouterProp;
}
v6版本React路由传参方式有三种:
Ø 动态路由参数(param)
以“/detail/:id”形式传递的数据
类组件通过如下方法得到
//首先当前组件先使用高阶组件withRouter,然后就可以像v5一样使用了。
this.props.router.match.params
函数组件可以通过如下方法跳转并传参
import { useNavigate,useParams,useLocation } from 'react-router-dom'
........
const navigate = useNavigate()
navigate('/detail/:id') //跳转方法
const params = useParams()
params.id //获取参数
Ø 查询字符串(query)
通过地址栏中的 home?key=value&key=value传递
类组件通过如下方法得到
//首先当前组件先使用高阶组件withRouter,然后就可以像v5一样使用了。
this.props.router.location.search
函数组件可以通过如下方法跳转并传参
import { useNavigate,useParams,useLocation } from 'react-router-dom'
........
const navigate = useNavigate()
navigate('/detail?key=value') //跳转方法
const location = useLocation()
location.search //获取参数
Ø 隐式传参(state),通过地址栏是观察不到的
通过路由对象中的state属性进行数据传递
类组件通过如下方法得到
//首先当前组件先使用高阶组件withRouter,然后就可以像v5一样使用了。
this.props.router.location.state
函数组件可以通过如下方法跳转并传参
import { useNavigate,useParams,useLocation } from 'react-router-dom'
........
const navigate = useNavigate()
navigate('/detail',{state={ key: value }}) //跳转方法
const location = useLocation()
location.state //获取参数
我们在App.js中通过useRoutes这个hooks来搭配路由。如下
export default function App1() {
let element = useRoutes([
{ path: "/", element: <Home /> },
{
path: "user",
element: <User />,
children: [
{ path: ":id", element: <User2 /> },
{ path: "user1", element: <User1 /> }
]
},
{ path: "*", element: <NotFound /> }
]);
return <>
//这里把上面使用hooks配置的全局路由在这里执行以下
{ element }
</>
}