【问题标题】:How to authenticate user with Context API?如何使用 Context API 对用户进行身份验证?
【发布时间】:2022-01-14 16:12:18
【问题描述】:

我无法使用 Context API 登录我的应用程序。当我在变量 session 的 localStorage 中没有任何令牌运行应用程序时,会出现很多错误,如下所示:

Uncaught TypeError: Cannot read properties of null (reading 'name')

我认为存在这个问题是因为我来自ApplicationContextcurrentAccount 为空。

dashboard/index.tsx

  const { currentAccount } = useContext(ApplicationContext);

  return (
      <span>{currentAccount.name}</span>
  );

routes.login 登录页面上,我也遇到了这些异常,即使此错误应该只出现在routes.dashboard 上:/ 刷新页面或清除 localStorage 无济于事。我在 ApplicationContextProvider 中也有一个无限循环 checkLogin :(

登录/index.tsx

  const { setCurrentAccount } = useContext(ApplicationContext);

  const onFinish = async (email: string; password: string) => {
      try {
        const response = await axios.post("/auth/login", {
            email: email,
            password: password
        });

        const token = response["token"];
        const account = response["account"];
        if (token && account) {
          localStorage.setItem("session", token);
          setCurrentAccount(account);

          history.push(routes.dashboard)
        }
      } catch (error) {

      }
  };

App.tsx

  return (
    <div className="App">
      <Switch>
        <ApplicationContextProvider>
          <Route path={route.login} component={Login} />
          <Main>
            <Route path={route.dashboard} component={Dashboard} />
          </Main>
        </ApplicationContextProvider>
      </Switch>
    </div>
  );

ApplicationContextProvider.tsx

export type AccountContext = {
  currentAccount?: Account;
  setCurrentAccount: (user: Account) => void;
  checkLogin: () => void;
};
export const ApplicationContext = React.createContext<AccountContext>(null);

interface ProviderProps {
  children: React.ReactNode
}

export const ApplicationContextProvider = ({ children }: ProviderProps) => {
  const [currentAccount, setCurrentAccount] = useState<Account>(null);

  useEffect(() => {
    checkLogin();
  }, [currentAccount]);

  const checkLogin = async () => {
    const token = localStorage.getItem("session");
    if (token) {
        const token = localStorage.getItem("session");
        const decode = jwt(token);
    
        const query = {
          id: decode["id"]
        }

        const response: Account = await api.get("/auth/account", query);
        setCurrentAccount(response);
    } else {
        setCurrentAccount(null);
    }
  };

  const stateValues = {
    currentAccount,
    setCurrentAccount,
    checkLogin
  };

  return (
    <ApplicationContext.Provider value={stateValues}>
      {children}
    </ApplicationContext.Provider>
  );

谁能告诉我我的上下文逻辑有什么问题,以验证用户到应用程序?

感谢您的帮助!

【问题讨论】:

    标签: javascript reactjs typescript


    【解决方案1】:

    我已经知道是怎么回事了,说不定以后对别人有用。

    我必须补充两件重要的事情。对于第一个 useEffect() 函数,需要有一个空的依赖数组,如下所示:

      useEffect(() => {
        checkLogin();
      }, [ ]);
    

    其次,我还必须添加状态以存储加载,如下所示:

    const [loading, setLoading] = useState(false)
    

    当我从 api 获取数据时设置正确的值等等

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-14
      • 2012-08-17
      • 2016-10-01
      • 2021-07-26
      相关资源
      最近更新 更多