英文:
React Router v6, guarded routes using Context API
问题
createBrowserRouter
使用 React Router,可以在此上下文中访问AppContext
信息。你可以通过以下方式来实现在你的场景中访问上下文信息:
import { useNavigate, useLocation } from 'react-router-dom';
function ProtectedRoute({ element: Component, ...rest }) {
const ctx = useContext(AppContext);
const navigate = useNavigate();
const location = useLocation();
if (ctx.token !== "") {
return <Component {...rest} />;
} else {
// Redirect to the login page and preserve the current location state
navigate('/login', { state: { from: location } });
return null;
}
}
通过使用useNavigate
和 useLocation
钩子,你可以轻松地在用户未登录时将用户重定向到登录页面,并在登录后返回到原来的页面。
英文:
I have the following setup:
App.js
import AppContext from './context/AppContext.js';
import router from './routes/routes.js';
function App() {
const [token, setToken] = useState("");
function login(token) {
setToken(token);
}
return (
<React.StrictMode>
<AppContext.Provider value={{ token, login }}>
<RouterProvider router={router} />
</AppContext.Provider>
</React.StrictMode>
);
}
export default App;
routes.js
export default createBrowserRouter([
{
path: "/",
element: <Root />,
children: [
{
path: "home",
element: <Home />
},
{
path: "admin",
element: <ProtectedRoute element={Admin} />
},
{
path: "login",
element: <Login />
}
]
}
]);
ProtectedRoute.js
export default function ProtectedRoute({ element: Component, ...rest }) {
const ctx = useContext(AppContext);
return (
ctx.token !== "" ? <Component /> : <Navigate to="/login" />
);
}
I want to be able check if the user is logged in by accessing information from a context, however the returned object always contains the default values. Is there a way to access context information with createBrowserRouter
in this scenario?
答案1
得分: 2
The protected route component should be refactored to be rendered as a layout route component by rendering an Outlet
instead of some passed prop.
import { Navigate, Outlet } from 'react-router-dom';
export default function ProtectedRoute() {
const { token } = useContext(AppContext);
return token
? <Outlet />
: <Navigate to="/login" replace />;
}
export default createBrowserRouter([
{
path: "/",
element: <Root />,
children: [
{ path: "home", element: <Home /> },
{
element: <ProtectedRoute />,
children: [
{
path: "admin",
element: <Admin />
},
// ... other protected routes
],
},
{ path: "login", element: <Login /> }
// ... other unprotected routes
]
}
]);
英文:
The protected route component should be refactored to be rendered as a layout route component by rendering an Outlet
instead of some passed prop.
import { Navigate, Outlet } from 'react-router-dom';
export default function ProtectedRoute() {
const { token } = useContext(AppContext);
return token
? <Outlet />
: <Navigate to="/login" replace />;
}
export default createBrowserRouter([
{
path: "/",
element: <Root />,
children: [
{ path: "home", element: <Home /> },
{
element: <ProtectedRoute />,
children: [
{
path: "admin",
element: <Admin />
},
// ... other protected routes
],
},
{ path: "login", element: <Login /> }
// ... other unprotected routes
]
}
]);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论