如何使用本地存储、反应钩子和上下文提供程序保持状态持久性 [英] How do I keep state persistant using local storage, react hooks, and Context Provider

查看:39
本文介绍了如何使用本地存储、反应钩子和上下文提供程序保持状态持久性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在我的应用程序中实施身份验证,我遇到的问题是刷新状态不是持久的,所以我被重定向回登录屏幕.如何使用 React Hooks 检查 local storage 中是否有 authToken 以保持我在刷新时登录.

I'm implementing authentication into my app, the issue I am having is on refresh the state is not persistent so I get redirected back to the login screen. How can I use React Hooks to check if there is an authToken in local storage to keep me logged in on refresh.

这是我的受保护路由,用于检查身份验证令牌

This is My Protected Route That checks for auth tokens

<Route
    {...rest}
    render={
        props=>
            authTokens ? (
                <Component {...props}/>
            ) : (
                <Redirect
                    to ={
                        {
                            pathname: '/login',
                            state: {
                                from: props.location
                            }
                        }
                    }
                />

这是我的登录页面功能

 function Login(props) {
const [isLoggedIn, setLoggedIn] = useState(false);
const [isError, setIsError] = useState(false);
const [firstName, setUserName] = useState("");
const [password, setPassword] = useState("");
const { setAuthTokens } = useAuth();

function postLogin() {
    axios.post("http://10.6.254.22:5000/userinformation/login", {
      firstName,
      password
    }).then(result => {
      if (result.status === 200) {
        console.log('You have been logged in as user: ' +result.data[0].firstName)
        setAuthTokens(result.data);
        setLoggedIn(true);
      } else {
        setIsError(true);
      }
    }).catch(e => {
      setIsError(true);
    });
  }


  if (isLoggedIn) {
    return <Redirect to="/" />;
  }

下面是包含状态的钩子

    const [authTokens, setAuthTokens] = useState();

  const setTokens = (data) => {
    localStorage.setItem("authTokens", JSON.stringify(data));
    setAuthTokens(data);
  }

  useEffect(()=> {
    let jsonToken = localStorage.getItem('authTokens', JSON.stringify(authTokens))
    console.log('JSON TOKEN  -----' + jsonToken)
    setAuthTokens(jsonToken)
  })

如何在加载时使用 local storage 变量设置状态 authTokens,以便刷新时状态不为空,因此我不会在页面重新加载时注销.还要提一下上下文提供者是这样设置的:

How can i set the state authTokens with the local storage variable on load so that when I refresh the state isnt empty so i dont get logged out on page reload. Also to mention The context provider is set up as so:

<AuthContext.Provider value={{ authTokens, setAuthTokens: setTokens}}>
   <ProtectedRoute path="/" exact component={ProfileBox}/>
</AuthContext.Provider>

推荐答案

问题是 authTokensundefined 当你的组件mounts,因此,受保护路由 的逻辑正在评估代码的 Redirect 部分,从而导致重定向到 /login.

The problem is that authTokens is undefined when your component mounts, so the logic of your Protected route is evaluating to the Redirect portion of your code, causing the redirection to /login.

React 将删除 componentWillMount 钩子,因此,我找到的解决此特定问题的方法是还检查 localStorage 中的令牌,而不是仅检查状态 authTokens.

React will remove componentWillMount hook, so, the solution I found to this specific problem, is to check also for the token in the localStorage, instead of just checking for the state authTokens.

这样,您的代码将能够评估您是否拥有令牌(甚至在第一次组件更新之前).

This way, your code will be able to evaluate that you have the token (even before the first component update).

Protected Route 的代码可能如下所示:

The code of your Protected Route may look like this:

<Route
    {...rest}
    render={
        props=>
            (authTokens || localStorage.getItem("authTokens")) ? (
                <Component {...props}/>
            ) : (
                <Redirect
                    to ={
                        {
                            pathname: '/login',
                            state: {
                                from: props.location
                            }
                        }
                    }
                />

其他可能的解决方案是:

Other possible solutions are:

  • 使用上下文
  • 使用 Redux

但我认为如果你只是想保护私有路由,这个方案就足够了

But I think that if you just want to protect private routes, this solution is sufficient

这篇关于如何使用本地存储、反应钩子和上下文提供程序保持状态持久性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆