![](/img/trans.png)
[英]How to dynamically render Route components in React-router-dom and React
[英]React-Router-Dom 6 - How to dynamically render a component?
我的舊方法:
<Route
key={i}
path={path}
render={(props) => {
if (!localStorage.getItem("token")) {
<Redirect
to={{ pathname: "/login", state: { from: props.location } }}
/>
}
return (
<AuthLayout>
<Component {...props} />
</AuthLayout>
);
}}
/>
用新element
替換render
給我:
函數作為 React 子項無效。 如果您返回一個組件而不是從渲染中返回,則可能會發生這種情況
顯然,新的 API 只是期望:
<Route
key={i}
path={path}
element={
<Component />
}
/>
我真正想要完成的是動態渲染組件:
{authProtectedRoutes.map(({ path, Component }, i) => {
<Route
key={i}
path={path}
element={
// If no auth token, redirect to login
if (!token) {
<Navigate to="/login" />
} else {
<AuthLayout>
<Component />
</AuthLayout>
}
}
/>
})}
不知道該怎么做...
編輯:
我的組件數組是這樣的:
const authProtectedRoutes = [
{ path: "/dashboard", Component: Dashboard },
{ path: "/pages-starter", Component: StarterPage },
當我嘗試在循環中返回Component
時,我得到:
React.jsx:類型無效——需要一個字符串(對於內置組件)或一個類/函數(對於復合組件)但得到:未定義。 您可能忘記從定義它的文件中導出您的組件,或者您可能混淆了默認導入和命名導入。
element={
// If no auth token, redirect to login
if (!token) {
<Navigate to="/login" />
} else {
<AuthLayout>
<Component />
</AuthLayout>
}
}
你不能在 jsx 中間做一個if
,但你可以做一個條件運算符:
element={!token ? (
<Navigate to="/login" />
) : (
<AuthLayout>
<Component />
</AuthLayout>
)}
element
屬性需要一個ReactNode
(又名 JSX )而不是 javascript(即 if 語句)。
由於您似乎批量呈現經過身份驗證的路由,因此更好的解決方案是將它們全部包裝在一個檢查令牌的AuthLayout
組件中。 它沒有渲染children
道具,而是渲染了一個用於渲染嵌套路由的Outlet
。
例子:
const AuthLayout = ({ token }) => {
// ... existing AuthLayout logic
return token
? (
<div /* awesome auth layout CSS style */>
...
<Outlet /> // <-- nested routes render here
</div>
)
: <Navigate to="/login" />;
};
不要忘記從 map 回調返回Route
。
<Route element={<AuthLayout token={token} />}>
{authProtectedRoutes.map(({ path, Component }) => (
<Route key={path} path={path} element={<Component />} />
))}
</Route>
很好的路由相關問題。 首先,我從 react-router-dom 的 github 找到了有用的代碼示例: https://github.com/remix-run/react-router/blob/2cd8266765925f8e4651d7caf42ebe60ec8e163a/examples/auth/src/App.tsx#L104#L104
在這里,作者建議實現額外的 RequireAuth 組件並在路由設置中使用它,而不是將一些邏輯放在“元素”或“渲染”中,如下所示:
<Route
path="/protected"
element={
<RequireAuth>
<SomePageComponent />
</RequireAuth>
}
....
這種方法將允許將與身份驗證相關的檢查封裝在這個新的 RequireAuth 組件中,從而使您的應用程序路由設置更加“輕量級”
作為一個“簡短”示例,我創建了以下您可以參考的代碼:
function App() {
return (
<BrowserRouter>
<AppRoutes />
</BrowserRouter>
);
}
const RequireAuth = ({ children }) => {
const token = localStorage.getItem('token');
const currentUrl = useHref();
return !token ? (
<Navigate to={`/login?redirect=${currentUrl}`} />
) : (
children
);
};
const authProtectedRoutes = [
{ path: '/', component: PaymentsPage },
{ path: '/user', component: UserInfoPage },
];
const AppRoutes = () => (
<Routes>
{authProtectedRoutes.map((r) => (
<Route
key={r.path}
path={r.path}
element={
<RequireAuth>
<AuthLayout>
<r.component />
</AuthLayout>
</RequireAuth>
}
/>
))}
<Route path="/login" element={<LoginPage />} />
<Route path="*" element={<NotFoundPage />} />
</Routes>
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.