开发者问题收集

React 从 localStorage 获取对象,无法使用 react useState 设置它

2021-10-28
1008

我有以下 App.js 代码。 useEffect 钩子将在应用程序启动时运行,我希望它从 localStorage 检索一个对象,然后将其设置为 useState 用户变量。

CONSOLE.LOG 输出:

JSON user {"name":"tester","username":"test username","password":"testpassword","token":"test token"}

parsed user {name: 'tester', username: 'test username', password: 'testpassword', token: 'test token'}

current logged in user: null

const App = (props) => {
  const [user, setUser] = useState(null);

  useEffect(() => {
    // CHECK IF THERE IS A LOGGED IN USER FROM PREVIOUS SESSIONS
    const loggedUserJSON = window.localStorage.getItem("loggedInUser");
    if (loggedUserJSON) {
      console.log("JSON user", loggedUserJSON);
      const parsedUser = JSON.parse(loggedUserJSON);
      console.log("parsed user", parsedUser);
      setUser(parsedUser);
    }
    console.log("current logged in user: ", user);
  }, []);

以下是我的登录组件的事件处理程序:

const login = async (event) => {
    event.preventDefault();
    try {
      const user = await UserService.login({
        username: username,
        password: password,
      });
      window.localStorage.setItem("loggedInUser", JSON.stringify(user));
      history.push("/home");
    } catch (exception) {
      console.log(exception);
    }
  };

现在我可以看到对象正确地进入浏览器的本地存储,我甚至可以根据我的 console.log 输出正确解析它。但不知何故

setUser(parsedUser);

不起作用。它给出了默认值 null。是什么导致 setUser 失败?

1个回答

setUser useState 函数不会立即将值分配给用户,例如 user = parsedUser 它的工作方式不同,它只会在下一次渲染中设置您的值,

检查此链接中的答案。

useState 设置方法未立即反映更改

解决方案

您可以在下一次渲染时检查值,也可以在另一个 useEffect 中检查更改

const App = (props) => {
  const [user, setUser] = useState(null);

  useEffect(() => {
    // CHECK IF THERE IS A LOGGED IN USER FROM PREVIOUS SESSIONS
    const loggedUserJSON = window.localStorage.getItem("loggedInUser");
    if (loggedUserJSON) {
      console.log("JSON user", loggedUserJSON);
      const parsedUser = JSON.parse(loggedUserJSON);
      console.log("parsed user", parsedUser);
      setUser(parsedUser);
    }
    console.log("current logged in user: ", user); // this will only print null because `setUser(parsedUser)` is not yet reflected 
  }, []);
console.log("current logged in user on every render: ", user);  // this will console the value on its second render, becase second render happens when ` setUser(parsedUser);` completed
}

检查更改的另一种方法是使用另一个 useEffect

const App = (props) => {
  const [user, setUser] = useState(null);

  useEffect(() => {
    // CHECK IF THERE IS A LOGGED IN USER FROM PREVIOUS SESSIONS
    const loggedUserJSON = window.localStorage.getItem("loggedInUser");
    if (loggedUserJSON) {
      console.log("JSON user", loggedUserJSON);
      const parsedUser = JSON.parse(loggedUserJSON);
      console.log("parsed user", parsedUser);
      setUser(parsedUser);
    }
    console.log("current logged in user: ", user); // this will only 
   print null becase `setUser(parsedUser)` is not yet reflected 
  }, []);
  useEffect(()=> {
     console.log("current logged in user on every render: ", user);  // this will console the value every time user value changes intially it will be null and on second time it will show your data
  },[user])
}
Sojin Antony
2021-10-28