【问题标题】:Using fetch to set state before the page renders在页面呈现之前使用 fetch 设置状态
【发布时间】:2021-06-02 13:05:41
【问题描述】:

我正在为 React 组件构建一个守卫。守卫接受 Auth0 JWT 并检查我们的 API 以查看该用户是否存在于我们的数据库中。如果用户确实存在,我们将userExists 设置为true 并将它们重定向到/dashboard。如果用户不存在,我们会调用postUser并将其发送给/complete-profile

我遇到的问题是页面在 userExists 被 fetch 调用正确设置之前呈现。换句话说,如果我要运行以下代码,日志将按以下顺序读取:

  1. 用户确实存在
  2. FETCH CALLED 1

const SomeGuard: FC<SomeGuardProps> = ({ children }) => {
  const { isAuthenticated } = useAuth();
  const isMountedRef = useIsMountedRef();

  const [userExists, setUserExists] = React.useState(true);

  const getUser = useCallback( async () => {
    try {
      var user_exists;
      fetch(`https://website.com/user`,
        {
          headers: {
            Authorization: `Bearer DFJKS54DUJ6DD.SDF2KJWEF4NKN3JKw4534.DFSKJ5HSKDJ6HF`,
          },
          method: 'GET',
        },
      ).then(response => {
        if (response.status===200) { // USER EXISTS
          console.log("FETCH CALLED 1")
          setUserExists(true);
        }
        else if (response.status===404) { // catch 404 -- USER NOT FOUND
          console.log("FETCH CALLED 2")
          setUserExists(false);
        }
        
        return response.json();
      })
    }
    catch (e) {
      console.error(e);
    }
  }, [isMountedRef]);


  const postUser = useCallback( async () => {
    // assume this works and sends a POST request to our API
    // to create a user
  )}


  useEffect(() => {
    console.log("STEP 1");
    getUser();
  }, [getUser]);



  if (isAuthenticated) {
    if (!userExists) {
      console.log("USER DOES NOT EXIST");
      postUser();
      return <Redirect to="/complete-profile" />;
    }
    else if (userExists) {
      console.log("USER DOES EXIST");
      return <Redirect to="/dashboard" />;
    }
  }

  if (!isAuthenticated) {
    console.log("TRIED TO HIT DASHBOARD WITHOUT BEING LOGGED IN");
    return <Redirect to="/login" />;
  }

  return (
    <>
      {children}
    </>
  );
};


SomeGuard.propTypes = {
  children: PropTypes.node
};

export default SomeGuard;

因为它在调用fetch 之前呈现页面,所以我最初设置userExists 的值始终决定呈现哪个页面。

请帮忙!我在这里想念什么?如何在页面呈现之前获取fetch 调用以更新userExists

【问题讨论】:

    标签: reactjs typescript react-redux auth0


    【解决方案1】:

    userExists 的初始值设置为其他值,例如null,这样您就可以将未加载页面与已加载和真/已加载和假页面区分开来。然后,只渲染孩子一次 userExists 不为空:

    const [userExists, setUserExists] = React.useState(null);
    
    if (isAuthenticated) {
        if (userExists === false) {
            console.log("USER DOES NOT EXIST");
            postUser();
            return <Redirect to="/complete-profile" />;
        }
        else if (userExists === true) {
            console.log("USER DOES EXIST");
            return <Redirect to="/dashboard" />;
        }
    }
    
    return userExists === null ? null : children;
    

    【讨论】:

    • return userExists === null ? null 在异步请求进行时应该不会渲染任何内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-25
    • 1970-01-01
    • 1970-01-01
    • 2017-01-18
    • 1970-01-01
    • 2020-11-12
    • 1970-01-01
    相关资源
    最近更新 更多