首页 > 解决方案 > useState 在 ReactJS 中的初始和每个后续渲染之后重置为默认值

问题描述

下面的代码没有返回任何错误,但也没有按照逻辑工作。

所以下面是两个组件, APP() 作为父组件, Signin() 作为子组件,在父组件中我使用 useEffect 并且每当发生渲染时,它首先使用 cookie 检查服务器是否有效,然后它将更新 siginalready=true (初始默认值为 false),然后将状态传递给子组件,但是当我下次刷新页面时,它会将 siginalready=false 作为初始值(这很奇怪,因为它应该在第一次之后已经是 true)。

这种重置 siginalready 状态值的行为正在影响项目,就像第二次一样(我单击帐户信息,它首先向我显示登录页面(siginalready = false),然后在不到一秒的时间内它向我显示帐户信息页面((siginalready =true)。我觉得这是我在 useEffect 函数中缺少的东西,但我看不出它有什么问题。任何建议。

这是来自父组件的片段。

import Signin from "./Component/Signin";

function App() {

  const [siginalready, setifsignedin] = useState(false);

  const [userinfonew, setUserinfo] = useState([]);



  let url = "http://localhost:5000/api/verifyifloginalready";

  let options = {
    credentials: "include",
    method: "POST",
  };
  let verifyifloginalready = new Request(url, options);


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



  function credentailverify() {
    (async () => {
      const x1 = await fetch(verifyifloginalready)
        .then((res) => {
          if (res.status == 400 || res.status == 401) {
            console.log(res.status);
            // to do call delete current  cookies function
            return setifsignedin(false);
          } else if (siginalready == false) {
            setifsignedin(true);

            return res.json();
          } else {
            return;
          }
        })
        .then((data) => {
          setUserinfo(data.data);
        })
        .catch((err) => console.log("err"));

      return x1;
    })();
  }

  return (
    <Router>
      <div className="App">
        <header className="header">
          <Nav userinfo={userinfonew} userstatus={siginalready} />
        </header>

        <div className="main">
          <Sidebar />
          <Switch>
            <Route
              path="/"
              exact
           
              render={(props) => <Home {...props} userinfo={userinfonew} />}
            />
           
            from router {/* render={props=>(<newComponent}/> )} */}
           
            />
            <Route
              path="/signin"
              exact
              render={(props) => (
                <Signin
                  {...props}
                  userinfo={userinfonew}
                  userstatus={siginalready}
                />
              )}
            />
           
          </Switch>
        </div>

        <div className="footer">
          <Footer />
        </div>
      </div>
    </Router>
  );
}

const Home = () => (
  <div>
    <h1> Home page</h1>
  </div>
);

export default App;

以下是 Child 组件的代码片段

function Signin({ userinfo, userstatus }) {
return (
    <div>
      {userstatus ? (
        <Useraccount newuserinfo={userinfo} updateduserstatus={userstatus} />
      ) : (
        <SigninOptions  />
      )}
    </div>
  );

}
export default Signin;

标签: javascriptreactjsreact-hooks

解决方案


但是当我下次刷新页面时,它会将 siginalready=false 作为初始值(这很奇怪,因为它在第一次之后就应该是真的)

这就是你所做的:

const [siginalready, setifsignedin] = useState(false);

siginalready获取false为默认值。credentailverify是一个异步函数,所以调用它需要时间setifsignedin(true)

这就是SigininOptions第一次渲染组件的原因。

您可以在成功登录后保存登录状态以解决此问题:

// Put this function outside of App component
const isLoggedIn = () => {
   // user info can be loaded after refresh
   return !!window.localStorage.getItem('user-info'); // !! : cast to boolean
}

// And then inside App component
const [siginalready, setifsignedin] = useState(isLoggedIn());

function credentailverify() {
    (async () => {
      const x1 = await fetch(verifyifloginalready)
        .then((res) => {
          if (res.status == 400 || res.status == 401) {
            console.log(res.status);
            // to do call delete current  cookies function
            window.localStorage.removeItem('user-info');
            return setifsignedin(false);
          } else if (siginalready == false) {
            setifsignedin(true);

            return res.json();
          } else {
            return;
          }
        })
        .then((data) => {
          setUserinfo(data.data);
          // save user login status
          window.localStorage.setItem('user-info', JSON.stringify(data.data));
        })
        .catch((err) => console.log("err"));

      return x1;
    })();
  }

重要提示:您可能希望使用 JWT for SPA 处理身份验证,包括在真实世界程序中做出反应。


推荐阅读