不能返回孩子渲染不更新

问题描述 投票:0回答:1
const PrivateRoute = ({ children }) => {
  const [user, setUser] = useLocalState("", "user");
  const [isAuthorized, setIsAuthorized] = useState(false);
  const [privilege, setPrivilege] = useState(null);
  const [shouldRender, setShouldRender] = useState(false);

  useEffect(() => {
    async function checkPriv() {
      if (user.hasOwnProperty("email")) {
        const response = await fetch("http://localhost:3001/check-authorization", {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({ email: user.email }),
        });

        const data = await response.json();
        console.log("data: ", data, "is authorized: ", data.isAuthorized, "is priv: ", data.privilege);
        setIsAuthorized(data.isAuthorized);
        setPrivilege(data.privilege);
        console.log("got data back");
        console.log(privilege);

        if (data.isAuthorized && data.privilege === "manager") {
          console.log("user found");
          setShouldRender(true);
        } else {
          console.log("priv failed");
          setShouldRender(false);
        }
      }
    }
    checkPriv();
  }, []);
  useEffect(() => {
    console.log("isAuthorized: ", isAuthorized);
    console.log("privilege: ", privilege);

    if (isAuthorized && privilege === "manager") {
      console.log("user found");
      setShouldRender(true);
    } else {
      console.log("priv failed");
      setShouldRender(false);
    }
  }, []);
  const renderedComponent = useMemo(()=>{
    console.log("rednsdsdk")
  if (shouldRender) {
    return children;
  } else {
    return <Navigate to="/" />;
  }
},[]);
return renderedComponent;
};
export default PrivateRoute;

我不明白为什么我不能在这里使用更新后的 shouldRender 值。我知道除非在 useEffect 中,否则 useStates 不会更新,但是在 useEffect 之外更新是否会被覆盖?如果这是一个愚蠢的问题,我很抱歉,仍然是新手。

我也试过在没有任何状态的情况下使用它,但它仍然没有用

node.js reactjs hook
1个回答
0
投票

好吧,让我帮你做很多清理和重写工作

const PrivateRoute = React.memo(({ children }) => {
  const [user, setUser] = useLocalState("", "user");
  const [isAuthorized, setIsAuthorized] = useState(false);
  const [privilege, setPrivilege] = useState(null);
  const [shouldRender, setShouldRender] = useState(false);

  const make_request = React.useCallback(async () => {
      return await fetch("http://localhost:3001/check-authorization", {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({ email: user.email }),
        })
       .then(res => res.json())
       .then(data => data);
}, [user])

  const checkPriv = React.useCallback(async () => {
      if (user.hasOwnProperty("email")) {
        const data = await make_request()


        console.log("data: ", data, "is authorized: ", data.isAuthorized, "is priv: ", data.privilege);
        setIsAuthorized(data.isAuthorized);
        setPrivilege(data.privilege);
        console.log("got data back");
        console.log(privilege);

        if (data.isAuthorized && data.privilege === "manager") {
          console.log("user found");
          // do something here if success
          setShouldRender(true);
        } else {
          console.log("priv failed");
          // do something here if it failed
          setShouldRender(false); 

         // since you want to navigate to "/" if the check is false, you can simply do it here
         document.location.assign('/')
        }
      }
    }, [user])

  useEffect(() => {
    checkPriv();
  }, []);
  
  
    return shouldRender ? children : '';
});


export default PrivateRoute;

使用 shouldRender 在显示内容之前检查用户是否被授权,

useCallback
是一个 React hook,用于在 React 中创建 memoised 回调函数,因此为了防止重新渲染问题,您可以在线了解更多关于 React hooks 的信息,我将请求放在函数之外以实现可重用性,并且我还记住了组件而不是您在代码中使用的 useMemo 函数,这些是 React JS 中创建具有最佳用户体验的 React 应用程序的最佳实践

你说 useState 除了在 useEffect 中不会更新,不,它可以在组件内的任何地方更新,要在函数或挂钩中使用状态,必须将状态变量作为依赖项传递给挂钩,否则它当你使用函数或钩子内部的状态时不会更新,以供解释

exampleState
是您想在函数内部使用的状态,使用它的最佳方法是将函数包装在 useCallback 挂钩中,并将状态作为依赖项传递给它,如下所示:

const exampleFn = React.useCallback(() => {
 // then when you call this function exampleState's value will be an updated value
}, [exampleState])

如果有帮助请告诉我

© www.soinside.com 2019 - 2024. All rights reserved.