如何使此代码与react路由器v6兼容



在ProtectedRoute.js中,我已经编码:

const ProtectedRoute = ({ component: Component, ...rest }) => {
const { loading, isAuthenticated, user } = useSelector((state) => state.user);
return (
<Fragment>
{!loading && (
<Routes>
<Route
{...rest}
render={(props) => {
if (!isAuthenticated) {
return <Navigate to="/login" />;
}
return <Component {...props} />;
}}
/>
</Routes>
)}
</Fragment>
);
};
export default ProtectedRoute;

在App.js中,我写为:

function App() {
const { isAuthenticated, user } = useSelector((state) => state.user);
useEffect(() => {
WebFont.load({
google: { families: ["Roboto", "Droid Sans", "Chilanka"] },
});
store.dispatch(loadUser());
}, []);
return (
<Router>
<Header />
{isAuthenticated && <UserOptions user={user} />}
<Routes>
<Route exact path="/" element={<Home />} />
<Route exact path="/product/:id" element={<ProductDetails />} />
<Route exact path="/products" element={<Products />} />
<Route path="/products/:keyword" element={<Products />} />
<Route exact path="/search" element={<Search />} />
<Route exact path="/login" element={<Authenticate />} />
<ProtectedRoute exact path="/account" element={<Profile />} />
</Routes>
<Footer />
</Router>
);
}
export default App;

错误提示:[ProtectedRoute]不是Route组件。Routes的所有组件子级必须是Route或<反应片段>。

是不是少了什么东西!谢谢

react-router-dom中,不再使用自定义路由组件。Routes组件可以仅具有RouteReact.Fragment组件作为子组件,而Route组件可以仅拥有Routes或其他Route组件作为父组件。

相反,包装器组件处理业务逻辑,并为嵌套的Route组件呈现children道具或Outlet,或为重定向呈现Navigate

渲染children

const ProtectedRoute = ({ children }) => {
const { loading, isAuthenticated, user } = useSelector((state) => state.user);
if (loading) return null;
return isAuthenticated
? children
: <Navigate to="/login" replace />;
};

<Route
path="/account"
element={(
<ProtectedRoute>
<Profile />
</ProtectedRoute>
)}
/>

渲染Outlet

import { Outlet } from 'react-router-dom';
const ProtectedRoute = () => {
const { loading, isAuthenticated, user } = useSelector((state) => state.user);
if (loading) return null;
return isAuthenticated
? <Outlet />
: <Navigate to="/login" replace />;
};

<Route path="/account" element={<ProtectedRoute />}>
<Route path="/account" element={<Profile />} />
</Route>

使用Outlet的好处是,您可以使用单个身份验证包装器组件,并在其中呈现任意数量的嵌套Route子级,而使用children方法,除非将嵌套路由包装在Routes组件中,否则无法呈现嵌套路由。

像这样翻转逻辑并检查ProtectedRoute内部的所有内容怎么样?

const ProtectedRoute = () => {
const { loading, isAuthenticated, user } = useSelector((state) => state.user);

if (loading) { return null; }
if (!isAuthenticated) {
return <Navigate to="/login" />;
}
return <Profile user={user} andWhateverElse={true} />;
};
export default ProtectedRoute;

function App() {
const { isAuthenticated, user } = useSelector((state) => state.user);
useEffect(() => {
WebFont.load({
google: { families: ["Roboto", "Droid Sans", "Chilanka"] },
});
store.dispatch(loadUser());
}, []);
return (
<Router>
<Header />
{isAuthenticated && <UserOptions user={user} />}
<Routes>
<Route exact path="/" element={<Home />} />
<Route exact path="/product/:id" element={<ProductDetails />} />
<Route exact path="/products" element={<Products />} />
<Route path="/products/:keyword" element={<Products />} />
<Route exact path="/search" element={<Search />} />
<Route exact path="/login" element={<Authenticate />} />
<Route exact path="/account" element={<ProtectedRoute />} />
</Routes>
<Footer />
</Router>
);
}
export default App;

最新更新