如何检查用户是否被 localStorage 登录并根据它重定向?
How to check if user is logged by localStorage and Redirect according to it?
我是 localStorage 和 React Router 的新手,我的目标是:
登录时将用户重定向到“/dashboard”,注销时重定向回“/home”。当然,如果他没有登录,也不允许他去 'dashboard'。出于某种原因,我在 App.js 中的代码不起作用:
function App() {
let userLogged;
useEffect(() => {
function checkUserData() {
userLogged = localStorage.getItem("userLogged");
}
window.addEventListener("storage", checkUserData);
return () => {
window.removeEventListener("storage", checkUserData);
};
}, []);
return (
<div className="App">
<React.StrictMode>
<Router>
<Routes>
<Route path="/" element={<Home />} />
{userLogged ? (
<Route path={"/dashboard"} element={<Dashboard />} />
) : (
<Route path={"/home"} element={<Home />} />
)}
</Routes>
</Router>
</React.StrictMode>
</div>
);
}
export default App;
我通过 localStorage.setItem('userLogged', false)
和 localStorage.setItem('userLogged', true)
在主页和控制面板中设置了它
您可以渲染路由并使用 Navigate
组件进行重定向。像这样-
// [...]
<Route path={"/dashboard"} element={<Dashboard />} />
<Route path={"/home"} element={<Home />} />
{
userLogged ?
<Navigate to="/dashboard" /> :
<Navigate to="/home" />
}
// other routes
无论何时注销,您都需要使用 useNavigate 挂钩手动重定向到所需的页面。
您只能从其他 window/browser 上下文中监听 localStorage 中的更改,而不能从同一 browser/window 上下文中监听。这里期望 window 知道它自己的状态。在这种情况下,您 实际上 需要一些 React 状态。
将 userLogged
转换为 React 状态变量并使用 useEffect
挂钩来初始化和持久化 userLogged
状态 to/from localStorage。不是有条件地渲染 Route
组件,而是创建一个包装器组件以从 localStorage 读取 userLogged
值,并有条件地为 nested/wrapped 路由 [=32 渲染一个 Outlet
=] 或 一个 Navigate
组件重定向到您的身份验证路由以登录。
示例:
import { Navigate, Outlet, useLocation } from 'react-router-dom';
const AuthWrapper = () => {
const location = useLocation(); // current location
const userLogged = JSON.parse(localStorage.getItem("userLogged"));
return userLogged
? <Outlet />
: (
<Navigate
to="/"
replace
state={{ from: location }} // <-- pass location in route state
/>
);
};
...
function App() {
const [userLogged, setUserLogged] = useState(
JSON.parse(localStorage.getItem("userLogged"))
);
useEffect(() => {
localStorage.setItem("userLogged", JSON.stringify(userLogged));
}, [userLogged]);
const logIn = () => setUserLogged(true);
const logOut = () => setUserLogged(false);
return (
<div className="App">
<React.StrictMode>
<Router>
<Routes>
<Route path="/" element={<Home logIn={logIn} />} />
<Route path={"/home"} element={<Home logIn={logIn} />} />
<Route element={<AuthWrapper />}>
<Route path={"/dashboard"} element={<Dashboard />} />
</Route>
</Routes>
</Router>
</React.StrictMode>
</div>
);
}
export default App;
首页
import { useLocation, useNavigate } from 'react-router-dom';
const Home = ({ logIn }) => {
const { state } = useLocation();
const navigate = useNavigate();
const loginHandler = () => {
// authentication logic
if (/* success */) {
const { from } = state || {};
// callback to update state
logIn();
// redirect back to protected route being accessed
navigate(from.pathname, { replace: true });
}
};
...
};
我是 localStorage 和 React Router 的新手,我的目标是: 登录时将用户重定向到“/dashboard”,注销时重定向回“/home”。当然,如果他没有登录,也不允许他去 'dashboard'。出于某种原因,我在 App.js 中的代码不起作用:
function App() {
let userLogged;
useEffect(() => {
function checkUserData() {
userLogged = localStorage.getItem("userLogged");
}
window.addEventListener("storage", checkUserData);
return () => {
window.removeEventListener("storage", checkUserData);
};
}, []);
return (
<div className="App">
<React.StrictMode>
<Router>
<Routes>
<Route path="/" element={<Home />} />
{userLogged ? (
<Route path={"/dashboard"} element={<Dashboard />} />
) : (
<Route path={"/home"} element={<Home />} />
)}
</Routes>
</Router>
</React.StrictMode>
</div>
);
}
export default App;
我通过 localStorage.setItem('userLogged', false)
和 localStorage.setItem('userLogged', true)
您可以渲染路由并使用 Navigate
组件进行重定向。像这样-
// [...]
<Route path={"/dashboard"} element={<Dashboard />} />
<Route path={"/home"} element={<Home />} />
{
userLogged ?
<Navigate to="/dashboard" /> :
<Navigate to="/home" />
}
// other routes
无论何时注销,您都需要使用 useNavigate 挂钩手动重定向到所需的页面。
您只能从其他 window/browser 上下文中监听 localStorage 中的更改,而不能从同一 browser/window 上下文中监听。这里期望 window 知道它自己的状态。在这种情况下,您 实际上 需要一些 React 状态。
将 userLogged
转换为 React 状态变量并使用 useEffect
挂钩来初始化和持久化 userLogged
状态 to/from localStorage。不是有条件地渲染 Route
组件,而是创建一个包装器组件以从 localStorage 读取 userLogged
值,并有条件地为 nested/wrapped 路由 [=32 渲染一个 Outlet
=] 或 一个 Navigate
组件重定向到您的身份验证路由以登录。
示例:
import { Navigate, Outlet, useLocation } from 'react-router-dom';
const AuthWrapper = () => {
const location = useLocation(); // current location
const userLogged = JSON.parse(localStorage.getItem("userLogged"));
return userLogged
? <Outlet />
: (
<Navigate
to="/"
replace
state={{ from: location }} // <-- pass location in route state
/>
);
};
...
function App() {
const [userLogged, setUserLogged] = useState(
JSON.parse(localStorage.getItem("userLogged"))
);
useEffect(() => {
localStorage.setItem("userLogged", JSON.stringify(userLogged));
}, [userLogged]);
const logIn = () => setUserLogged(true);
const logOut = () => setUserLogged(false);
return (
<div className="App">
<React.StrictMode>
<Router>
<Routes>
<Route path="/" element={<Home logIn={logIn} />} />
<Route path={"/home"} element={<Home logIn={logIn} />} />
<Route element={<AuthWrapper />}>
<Route path={"/dashboard"} element={<Dashboard />} />
</Route>
</Routes>
</Router>
</React.StrictMode>
</div>
);
}
export default App;
首页
import { useLocation, useNavigate } from 'react-router-dom';
const Home = ({ logIn }) => {
const { state } = useLocation();
const navigate = useNavigate();
const loginHandler = () => {
// authentication logic
if (/* success */) {
const { from } = state || {};
// callback to update state
logIn();
// redirect back to protected route being accessed
navigate(from.pathname, { replace: true });
}
};
...
};