在ReactJS进行初始渲染和所有后续渲染之后,useState会重置为默认值

时间:2020-07-03 19:48:26

标签: javascript reactjs react-hooks

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

因此,以下是两个组件,APP()作为父组件,Signin()作为子组件,在父组件中,我使用useEffect,并且每当出现渲染时,它首先使用cookie检查服务器是否有效,然后将更新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;

下面是子组件的代码片段

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

}
export default Signin;

1 个答案:

答案 0 :(得分:1)

但是当我下次刷新页面时,它的初始值为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处理身份验证,包括在真实程序中进行反应。