尝试使用react钩子进行经过身份验证的路由,下面的代码段在刷新页面时出现,而令牌可用时,它在第一次渲染时不会在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/