React useState挂钩未在异步useEffect中更新

时间:2020-10-28 21:25:37

标签: reactjs react-hooks use-state

我想用我保存在localStorage中的对象覆盖用户,但是它不起作用。

注意,该组件称为 Index ,因为我正在使用next.js

import React, { useState, useEffect } from 'react';
import { loadUser } from '../utils/user';

const Index = () => {
  const [ user, setUser ] = useState({});

  async function restore(){
    const loadedUser = await loadUser();
    console.log(loadedUser);                    // correct - {userId: 4124783261364}
    setUser(loadedUser); 
    console.log(user);                          // was not updated - {}
  };

  useEffect(() => {
    restore();
  }, [0])

  return (<></>);
};

export default Index;

2 个答案:

答案 0 :(得分:1)

问题

  • 如果您要运行效果并仅清理一次(在 mount unmount 上),则可以传递一个空数组( [] )(不是[0] ),作为第二个参数。这告诉React,您的效果不依赖于道具或状态的任何值,因此它从不不需要重新运行
  • 与通过扩展React.Component或React.PureComponent创建的类组件中的setState 相似,使用 useState钩子提供的更新程序进行的状态更新也是异步的,并且< strong>不会立即得到体现。这是为什么 console.log(user); 不显示更新值的原因

解决方案

setUser(loadedUser);

类似情况

摆脱了问题,因为您只需要一次从本地存储中加载用户。但是当 const restore = async () => { const loadedUser = await loadUser(); console.log(loadedUser); // correct - {userId: 4124783261364} setUser(loadedUser); console.log(user); // user is not updated here, but will be }; useEffect(() => { restore(); }, []); 按时间返回更改结果,因此需要实时更新用户时,您应该使用 loadUser()

useCallback

答案 1 :(得分:-1)

尝试这样的事情:

// Assuming your loadUser() functions is set like the line below
const loadedUser = {userID: '513216351354'};


const Index = () => {

function restore(){
  console.log("Loaded user is " + loadedUser.userID);       // Loaded user is 513216351354
  setUser(loadedUser.userID); 
  console.log("User is " + user);                          // User is 513216351354
};

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

return (<></>);
}

export default Index;