React Router v6 路由重定向指南
问题描述
在 React Router v6 中,许多开发者遇到了路由重定向的问题。与 v5 版本不同,v6 中不再支持在 Route
组件中使用 render
属性来实现重定向功能。当尝试使用类似 v5 的语法时,会出现 TypeScript 错误:Property 'render' does not exist on type...
。
解决方案
1. 使用 Navigate 组件进行基本重定向
React Router v6 引入了 Navigate
组件来替代 v5 中的 Redirect
组件:
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom';
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/lab" element={<Lab />} />
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
</BrowserRouter>
提示
使用 replace
属性可以避免在浏览器历史记录中创建多余的条目,保持历史记录清洁。
2. 处理 404 路由
使用通配符路径 *
来捕获所有未匹配的路由:
<Route path="*" element={<Navigate to="/" replace />} />
或者显示自定义的 404 页面:
<Route path="*" element={<NotFound />} />
3. 条件重定向
根据应用状态进行条件重定向:
// 在组件内部使用
import { useState } from "react";
import { Navigate } from "react-router-dom";
function ProtectedComponent() {
const [isLoggedIn] = useState(false);
if (!isLoggedIn) {
return <Navigate to="/login" replace />;
}
return <div>受保护的内容</div>;
}
4. 编程式导航
使用 useNavigate
hook 进行编程式导航:
import { useNavigate } from "react-router-dom";
function MyComponent() {
const navigate = useNavigate();
const handleRedirect = () => {
// 替换当前历史记录
navigate("/target-path", { replace: true });
// 或者添加新历史记录(默认行为)
// navigate("/target-path");
};
return (
<button onClick={handleRedirect}>
跳转到目标页面
</button>
);
}
5. 认证保护路由
创建高阶组件来保护需要认证的路由:
import { useLocation, Navigate } from "react-router-dom";
import { useAuth } from "../hooks/Auth";
export function RequireAuth({ children }) {
let { user } = useAuth();
let location = useLocation();
if (!user) {
return <Navigate to="/login" state={{ from: location }} replace />;
}
return children;
}
使用保护路由:
<Route
path="/dashboard"
element={
<RequireAuth>
<Dashboard />
</RequireAuth>
}
/>
6. 保留参数的重定向
当需要重定向并保留 URL 参数时,可以使用自定义组件:
import { useEffect } from 'react';
import { generatePath, useNavigate, useParams } from 'react-router-dom';
function Redirect({ to }) {
const navigate = useNavigate();
const params = useParams();
useEffect(() => {
navigate(generatePath(to, params), { replace: true });
}, [navigate, to, params]);
return null;
}
// 使用方式
<Route path="/users/:id" element={<Redirect to="/new-path/:id" />} />
常见问题解答
注意
React Router v6 不再支持在 Route 组件中使用 render
、component
或 children
属性,请使用 element
属性代替。
Q: 如何从类组件中进行重定向?
A: 对于类组件,可以使用高阶组件(HOC)来注入导航功能:
import { useNavigate } from 'react-router-dom';
export const withRouter = WrappedComponent => props => {
return <WrappedComponent {...props} navigate={useNavigate()} />;
};
// 在类组件中使用
class MyComponent extends React.Component {
// ...
handleRedirect = () => {
this.props.navigate("/target-path");
}
// ...
}
export default withRouter(MyComponent);
Q: 重定向时如何传递状态?
A: 使用 state
属性传递状态数据:
navigate("/target-path", {
state: { message: "重定向提示信息" },
replace: true
});
总结
React Router v6 对重定向机制进行了重大改进,主要变化包括:
- 使用
Navigate
组件替代Redirect
组件 - 使用
useNavigate
hook 替代useHistory
hook - 推荐使用
replace
选项保持历史记录清洁 - 通配符路由
*
用于处理未匹配的路由
通过掌握这些技巧,你可以轻松地在 React Router v6 中实现各种重定向需求,创建更流畅的用户体验。