持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情
组件方面
React-Router6版本移除了<Switch/>组件,并使用<Routes/>替换。v5中Switch可以根据当前的路由 path ,匹配唯一的 Route 组件加以渲染。但是 Switch 本身是可以被不用的,v6则必须使用Routes。
React-Router6移除了<Redirect/>组件,但可以使用新增的<Navigate/>组件配合<Route/>组件实现重定向效果。注:Navigate可接收绝对路径和相对路径
属性方面
React-Router6版本移除了component与render属性,使用element属性替代
代码演示
React-Router5 设置路由组件
<Switch>
<Route path="/home" component={Home} />
<Route path="/login" render={()=><Login/>}/>
</Switch>
React-Router6 设置路由组件
<Routes>
<Route path="/home" element={<Home/>} />
<Route path="/login" element={<Login/>} />
</Routes>
React-Router5 设置重定向
<Route path='/user'}>
<Redirect to="/user/info" />
{/* <Redirect to="info" /> */}
</Route>
React-Router6 设置重定向
<Route path="/user" element={<Navigate to="/user/info"/>}>
<Route path="/user" element={<Navigate to="../info"/>}>
props方面
React-Router5路由组件props会自动添加history、location、match三个路由相关属性用来操作路由,其中history用来进行路由跳转,location用来进行参数获取,match用来获取params参数。
注意:并且不是路由组件想要使用路由属性也是可以的,可以使用withRouter高阶组件包裹和和相应的hooks如useHistory、useRouteMatch、useParams来实现。
其中
-
`useHistory`获取 `history` 对象 -
`useRouteMatch`获取当前路由的匹配信息 -
`useParams`获取 url 上的动态路由信息
但是在React-Router6中,路由组件props不再自动注入history、location、match三个路由相关属性。并且移除了withRouter高阶组件
代码演示-实现路由跳转
React-Router5
1.声明式导航
(1)字符串形式
<Link to="/home" />
(2)对象形式
<Link to={{ pathname: "/home" }} />
2.编程式导航
(1)函数组件
//使用props
props.history.push("/home")
props.history.replace("/home")
//使用hooks
const history = useHistory("/home")
history.push("/home")
history.replace("/home")
(2)类组件
this.props.history.push("/home")
this.props.history.replace("/home")
React-Router6
封装withRouter高阶组件
作用:使类组件可以使用路由
import { useLocation, useNavigate, useParams } from "react-router";
// https://github.com/remix-run/react-router/issues/7256
export default function withRouter(Child) {
return (props) => {
const location = useLocation();
const navigate = useNavigate();
const params = useParams()
return (
<Child {...props} navigate={navigate} location={location} params={params} />
) } }
路由跳转
1.声明式导航
(1)字符串形式
<Link to="/home">home</Link>
(2)对象形式
<Link to={{ pathname: "/home"}}>home</Link>
2.编程式导航
(1)函数组件
// 函数组件通过props.navigate或useNavigate实现跳转。
(2)类组件
// 类组件通过高阶组件withRouter中的this.props.navigate实现跳转。
(3)实现跳转
// navigate 相对路径形式
navigate("../home1/home11");
// navigate 绝对路径形式
navigate("/home/home1/home11");
// navigate 对象形式
navigate({ pathname: "/home/home1/home11"});
参数方面
React-router5
传参
支持params、search、state三种参数。
1.声明式导航
(1)字符串形式
<Link to="/home?sort=name" />
(2)对象形式
<Link to={{
pathname: "/home",
search: "?sort=name",
hash: "#the-hash",
state: { flag: true }
}} />
2.编程式导航
(1)函数组件
// 函数组件通过props.navigate或useNavigate实现跳转。
字符串形式
props.history.push("/home?sort=name")
对象形式
props.history.push({
pathname: "/home",
search: "?sort=name",
hash: "#the-hash",
state: { flag: true }
})
(2)类组件
// 类组件通过高阶组件withRouter中的this.props.navigate实现跳转。
字符串形式
this.props.history.push("/courses?sort=name")
对象形式
this.props.history.push({
pathname: "/courses",
search: "?sort=name",
hash: "#the-hash",
state: { flag: true }
})
获取
params需要我们配置动态路由,然后在路由的match.params或者在函数组件中使用useParams获取。
search使用前需要使用URLSearchParams封装。
state传递参数需要注意的一点是当使用HashRouter的时候,页面刷新state参数会丢失。
1.类组件
获取search参数
this.props.location.search
获取state参数
this.props.location.state
获取params
this.props.match.params
2.函数组件
使用props
获取search参数
props.location.search
获取state参数
props.location.state
获取params
props.match.params
使用hooks
const location = useLocation()
获取search参数
location.search
获取state参数
location.state
获取params
match.useParams()
React-router6
传参
在类组件中使用withRouter高阶组件获取navigate来进行路由的跳转和传参。
在函数组件我们使用useNavigate获取navigate来进行路由的跳转和传参。
1.声明式导航
字符串形式
<Link to="home?name=home1#hash1" state={{ num: 1 }}>home</Link>
对象
<Link to={{
pathname: "home2",search: "?name=home2",hash: "#hash2",}}
state={{ num: 1 }}>home2</Link>
2.编程式导航
navigate 相对路径形式
navigate("../home3", { state: { num: "hh" } });
navigate 绝对路径形式
navigate("/home/home3",
{ state:
{ num: "hh" },
replace: true,//重定向
});
获取
params需要我们配置动态路由,在类组价我们可以使用自己封装的withRouter高阶组件通过params获取。在函数组件中使用useParams获取。
search在类组价中使用withRouter高阶组件中的location获取。在函数组件可以使用useSearchParams或useLocation获取。
state在类组价中使用withRouter高阶组件中的location获取。在函数组件可以使用useLocation获取。需要注意当使用HashRouter的时候,页面刷新state参数会丢失。
1.类组件
(1)获取search参数
this.props.location.search
(2)获取state参数
this.props.location.state
(3)获取params
this.props.params
2.函数组件
(1)使用props
//获取search参数
props.location.search
// 获取state参数
props.location.state props.params
// 获取params
(2)使用hooks
// 获取search参数
const location = useLocation()
const params = useParams() location.search
// 获取state参数
location.state
// 获取params
match.params
// 获取search参数
let [searchParams, setSearchParams] = useSearchParams()
searchParams.get(xxx)
嵌套方面
React-router5
子路由配置需要写到对应的子页面,子路由需要补全父路由路径
// App.jsx 父组件
<Switch>
<Route path="/home" component={<Home/>} />
<Route path="/user" component={<User/>} />
</Switch>
// User.jsx 子组件
<Switch>
<Route path="/user/info" component={<UserInfo/>} />
<Route path="/user/detail" component={<UserDetail/>} />
</Switch>
React-router6
子路由可简写
App.jsx 父组件
<Routes>
<Route path="/home" element={<Home/>} />
<Route path="/user/*" element={<User/>} />
</Routes>
User.jsx 子组件
<Routes>
<Route path="info" element={<UserInfo/>} />
<Route path="detail" element={<UserDetail/>} />
</Routes>
实现类似vue的router-view效果
App.jsx 父组件
<Routes>
<Route path="/home" element={<Home/>} />
<Route path="/user" element={<User/>}>
<Route path="info" element={<UserInfo/>} />
<Route path="detail" element={<UserDetail/>} />
</Route>
</Routes>
User.jsx 子组件
<Outlet />
通过配置渲染路由
React-Router5 使用 map 或 react-router-config通过配置渲染路由
定义routes
// routerConfig/routes.js
import Father from "./Father";
import Son1 from "./Son1";
import Son2 from "./Son2";
const routes = [
{
component: Fahter,
exact: true,//精确查找
path: "/father",
routes: [
{
path: "/Father/Son1",
component: Son1,
},
{
path: "/Father/Son2",
component: Son2,
},
],
},
];
export default routes;
在根组件,我们需要自己使用map遍历渲染,并把子路由通过routes传递下去。
import routes from "./routerConfig/routes";
<BrowserRouter>
<Switch>
{routes.map((route) => {
return (
<Route
path={route.path}
key={route.path}
render={(props) => {
return (
<route.component
{...props}
routes={route.routes}
></route.component>
);
}}
></Route>
);
})}
</Switch>
</BrowserRouter>
在子组件我们还需要继续使用map遍历渲染。
// Parent.js
<Switch>
{props.routes.map((route) => {
return (
<Route
path={route.path}
key={route.path}
render={(props) => {
return (
<route.component
{...props}
routes={route.routes}
></route.component>
);
}}
></Route>
);
})}
</Switch>
使用react-router-config插件简化代码
下包yarn add react-router-config
在根组件使用renderRoutes方法
import { renderRoutes }
from "react-router-config";
import routes from "./routerConfig/routes";
{renderRoutes(routes)}
在子组件使用renderRoutes
{renderRoutes(props.routes)}
React-Router6 使用useRoutes
首先定义routes
// routerConfig/routes.js
import Father from "./Father";
import Son1 from "./Son1";
import Son2 from "./Son2";
const routes = [
{
element: <Father></Father>,
path: "/father",
children: [
{
path: "Son1",
element: <Son1></Son1>,
},
{
path: "Son2",
element: <Son2></Son2>,
},
],
},
];
根组件中
import { useRoutes } from "react-router-dom";
import routes from "./routerConfig/routes";
function App() {
return {useRoutes(routes)}
}
子组件中,使用Outlet渲染
import { Outlet } from "react-router-dom";
<Outlet />
参考
基本使用苏苏同学
原理分析我不是外星人