尝试使用 react Hook 创建经过身份验证的路由,使用下面的代码片段,当我在 token 可用时刷新页面时,它会出现在第一次渲染时不会在 useEffect 中被拾取。我在这里做错了什么
const AuthRoute = ({ component: Component, ...rest }) => {
const context = useContext(AuthStateContext)
const token = window.localStorage.getItem('token')
useEffect(() => {
if (token) {
context.setLogin()
}
console.log("TOKEN ->", token)
}, [])
return (
<Route
{...rest}
render={props => (
context.isAuthenticated ?
<Component {...props} />
: <Redirect to={{
pathname: "/",
state: { from: props.location }
}} />
)}
/>
)
}
最佳答案
我假设context.setLogin()
将设置context.isAuthenticated
至true
。如果是这样的话,那就解释得通了。
useEffect(callback)
的回调函数总是在每次渲染之后异步调用。从第一次渲染开始,setLogin()
仅在 isAuthenticated
的值之后被调用已读取,访问时应为 false
.
因此渲染逻辑转到第二个分支 <Redirect />
它立即将用户带到其他地方。
要实现此目的,您可以推迟 isAuthenticated
的渲染 util 状态已决定。
(在这里,我假设您想要在渲染树中尽早检查并设置 isAuthenticated
一次,然后将 isAuthenticated
到 AuthStateContext
对象广播到应用程序的其他部分注意。)
我建议这种模式:
const AuthRoute = ({ component: Component, ...rest }) => {
const context = useContext(AuthStateContext)
const [authChecked, setAuthChecked] = useState(false)
useEffect(() => {
const token = window.localStorage.getItem('token')
if (token) context.setLogin()
setAuthChecked(true)
console.log("TOKEN ->", token)
}, [])
if (!authChecked) return null // <-- the trick!
return (
<Route
{...rest}
render={props => (
context.isAuthenticated ?
<Component {...props} />
: <Redirect to={{
pathname: "/",
state: { from: props.location }
}} />
)}
/>
)
}
旁注,如果 context.setLogin()
仅异步设置 isAuthenticated
的状态,那么您需要添加回调或 promise 模式,例如
context.setLogin(() => setAuthChecked(true))
// or
context.setLogin().then(() => setAuthChecked(true))
关于javascript - 使用 React、React Hooks 的私有(private)路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60861816/