使用Apollo + useContext进行身份验证(SSR)不必要的重新渲染

时间:2020-05-19 00:09:00

标签: javascript reactjs next.js apollo

由于useQuery在我不希望出现时被调用,因此我似乎正在报废

第一次加载,isAuthenticated的状态通过一个函数实例化,该函数对服务器进行查询以根据附加的标头获取userId。 如果存在有效的标头,则将isAuthenticated设置为true并因此调用useMemo(因为isAuthenticated是一个依赖项)。 useMemo调用setUser,它将userId和角色放入上下文中,以通过AuthProvider向下传递(在_app中,包装除ApolloProvider之外的所有内容)。

我使用导航栏中的userId(通过useContext)来获取头像(以及应用程序其余部分中的其他内容)。我注意到的是,每当我单击某些内容(例如,单独的查询过滤产品)时,都会调用CURRENT_USER中的_app查询。这表现为导航栏丢失了传递给它的useId数据一秒钟,然后恢复原状。因此,每次单击事物时,导航栏都会重新渲染。我不明白为什么CURRENT_USER查询一直被称为...

对于上下文,我在另一个没有SSR且没有问题的应用中使用相同的设置。

auth.context.js

import React, { useState, useEffect, useMemo} from "react";
import { CURRENT_USER } from "graphql/query/customer.query";
import { gql, useQuery } from "@apollo/client";
import { isBrowser } from "components/helpers/isBrowser";

export const AuthContext = React.createContext({});

export const AuthProvider = ({ children }) => {
  const { data, error, loading } = useQuery(CURRENT_USER, {
    onCompleted: () => {
      console.log("called query", data);
    },
    ssr: true,
  });
  const isValidToken = () => {
    if (isBrowser) {
      const token = localStorage.getItem("token");
      if (error) {
        return false;
      }
      if (!loading && !data) {
        return false;
      }
      if (token && data?.currentUser) {
        console.log(data.currentUser);
        return true;
      }
      if (!token) {
        return false;
      }
    }
  };
  const [isAuthenticated, makeAuthenticated] = useState(isValidToken());
  const [user, setUser] = useState({});
  function authenticate() {
    console.log(isAuthenticated);
    makeAuthenticated(isValidToken());
  }
  useEffect(() => {
    console.log("attempted to run");
    if (data && isAuthenticated) {
      setUser(data.currentUser);
      console.log("user", user);
    }
  }, [isAuthenticated]);
  function signout() {
    makeAuthenticated(false);
    localStorage.removeItem("token");
  }
  return (
    <AuthContext.Provider
      value={{
        isAuthenticated,
        authenticate,
        signout,
        user,
      }}
    >
      {children}
    </AuthContext.Provider>
  );
};

“ @ apollo / client”:“ ^ 3.0.0-beta.44”,

“下一个”:“ ^ 9.3.6”,

“反应”:“ ^ 16.13.1”,

0 个答案:

没有答案