【问题标题】:How to async fetch data in useEffect如何在useEffect中异步获取数据
【发布时间】:2021-11-20 15:13:10
【问题描述】:

我有一些问题。当我在 useEffect 中异步获取数据(使用 axios 进行获取)时,以及在我将响应数据设置为状态后,使用 useState 挂钩。然后页面渲染之前我得到了服务器的响应。 为了演示这个问题,我将 console.log 用于获取当前状态,然后得到“未定义”:

const [positions, setPositions] = useState([]);

useEffect(() => {
    const fetchPositions = async () => {
        const response = await EmployeeService.getEmployeePositions();
        setPositions(response.data);
    };
    
    fetchPositions();
    console.log('positions from state: ', positions); //undefined
}, []);

从“EmployeeService”获取数据的方法:

getEmployeePositions(){
    return axios.get(EMPLOYEE_API_BASE_URL + '/positions');
}

提前致谢,并致以最诚挚的问候!

【问题讨论】:

  • console.log 永远不会记录结果,因为在异步函数完成之前结果不存在。 undefined 是正确且预期的结果。
  • 请注意,setPositions 不会立即生效,因此可以未定义 stackoverflow.com/a/54069332/507203

标签: reactjs async-await use-effect use-state


【解决方案1】:

React 需要重新渲染才能显示结果。 这意味着您需要在 setState 时导致的后续重新渲染中捕获结果。 将控制台日志移到 useEffect 之外

const [positions, setPositions] = useState([]);

useEffect(() => {
    const fetchPositions = async () => {
        const response = await EmployeeService.getEmployeePositions();
        setPositions(response.data);
    };

    fetchPositions();
}, []);

console.log('positions from state: ', positions); // NOT UNDEFINED

React 总是会在你有数据之前渲染一次。 所以你可以用条件来捕捉它。

if (positions.length === 0) {
   return null;
}

【讨论】:

    【解决方案2】:

    您的代码没有问题,useEffect 始终未定义,因为它读取了渲染应用程序的第一个值。 要更新 useEffect 中的状态,请将参数放在数组 [] 上,但在您的情况下,它将导致无限循环。

    尝试在异步函数中记录

    const [positions, setPositions] = useState([]);
    
    useEffect(() => {
        const fetchPositions = async () => {
            const response = await EmployeeService.getEmployeePositions();
            setPositions(response.data);
            console.log('data from response: ', response);
        };
        
        fetchPositions();
        
    }, []);
    
    

    或者这样做

    const [positions, setPositions] = useState([]);
    
    useEffect(() => {
        const fetchPositions = async () => {
            const response = await EmployeeService.getEmployeePositions();
            setPositions(response.data);
            console.log('data from response: ', response);
        };
    
        if((positions ?? []).length == 0){
        fetchPositions();
        console.log('this is position state before fetch~>',positions)
        } else{
        console.log('this is position state after fetch~>',positions)
        }
    }, [positions]);
    

    【讨论】:

      猜你喜欢
      • 2021-06-06
      • 2021-08-13
      • 1970-01-01
      • 2022-09-23
      • 2022-01-13
      • 1970-01-01
      • 1970-01-01
      • 2021-04-14
      • 2021-03-15
      相关资源
      最近更新 更多