【问题标题】:How to synchronously get data using Axios?如何使用axios同步获取数据?
【发布时间】:2022-01-25 20:59:09
【问题描述】:

我正在尝试从 Axios 获取数据,但我认为在获取数据时会执行 return 语句。

import axios from 'axios'
import React, { useState, useEffect} from 'react'

export default function Overall() {

const [post, setPost] = useState({
    date:null,
    total:null
});

useEffect(() => {
    async function fetchData(){
        
        await axios.get(`https://data.covid19india.org/v4/min/data.min.json`).then((response) => {
            console.log("Inside Then block");
            setPost({'total':Object.entries(response.data).map(([k,v])=>
                // console.log(k,v.meta.last_updated,v.total.confirmed)
                v.total.confirmed
                ).reduce((prev, curr)=>prev+curr,0)
                })
            setPost({'date':Object.entries(response.data)[0][1].meta.last_updated})
        });
    }
    fetchData()
    console.log("Data Fetched");
    
}, []);

console.log("Post: ",post);
return (
    <div className='overall-container'>
        <div>
            <h2>India</h2>
        </div>
        <div>
            <h2>Total: {post.total}</h2>
            <h2>Date: {post.date}</h2>
        </div>

    </div>
  )
}

问题是,作为回报,只有{post.date} 可以工作,而{post.curr} 不能。我不知道为什么?我是新手,所以我不太了解。如果有人能解释一下,我将不胜感激。

【问题讨论】:

  • (1) 您正在覆盖post 状态下的数据,而不是合并它们,(2) 如果您正在使用 await,则无需使用 .then()

标签: reactjs react-hooks axios


【解决方案1】:

我假设您的意思是 {post.total} 而不是 {post.curr}

你可以改变:

            setPost({'total':Object.entries(response.data).map(([k,v])=>
                // console.log(k,v.meta.last_updated,v.total.confirmed)
                v.total.confirmed
                ).reduce((prev, curr)=>prev+curr,0)
                })
            setPost({'date':Object.entries(response.data)[0][1].meta.last_updated})

收件人:

setPost({
    total: Object.entries(response.data).map(([k,v])=>
           // console.log(k,v.meta.last_updated,v.total.confirmed)
           v.total.confirmed
           ).reduce((prev, curr)=>prev+curr,0),
    date: Object.entries(response.data)[0][1].meta.last_updated
});

它应该可以工作。但是,也许将日期和总计分成两个不同的状态会更好?

【讨论】:

  • 它有效。请您告诉我为什么它现在可以工作?
  • 好吧 setPost 就像你的帖子状态的设置器,所以当你有两个设置器时(让我们调用总设置器 A​​ 和日期设置器 B)。 setter A 设置已定义总计且未定义日期的发布状态。然后在设置者 B 设置后状态后,总计未定义且日期已定义。所以在 B 执行之后,总没有定义。
  • 是的,而且当你使用 await 时,也不需要使用 .then。你可以只做const response = await axios.get(...)
【解决方案2】:

在 useEffect 中执行异步操作是一种不好的做法。您应该创建一个单独的函数并从 useEffect 调用它。

您的错误是因为您调用 setPost 来更新总数,然后再次更新日期。

当您调用 setPost 时,它会删除 post 的先前值。如果您需要保留以前的值,您可以这样做:

setPost((prev) => ({
  ...prev,
  date: new Date()
}));

在您的代码中,您应该只调用一次 setPost

import React, { useState, useEffect} from 'react'
import axios from 'axios'

export default function Overall() {

const [post, setPost] = useState({});

const fetchData = async () => {
    try {
        const response = await axios.get(`https://data.covid19india.org/v4/min/data.min.json`)
        // tranform your response and then set it to state at once
        const total =  1 // replace with your total
        const date = new Date() // replace with your date
        setPost({ total, date })
    } catch(err) {
        console.log(err);
    }
}

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

console.log("Post: ",post);
return (
    <div className='overall-container'>
        <div>
            <h2>India</h2>
        </div>
        <div>
            <h2>Total: {post?.total}</h2>
            <h2>Date: {post?.date}</h2>
        </div>

    </div>
  )
}

【讨论】:

  • This is a bad practice to do async stuff in useEffect. 你能解释一下为什么吗?
  • 啊 nvm 你刚刚将它添加为单独的异步函数。
猜你喜欢
  • 2021-01-25
  • 1970-01-01
  • 1970-01-01
  • 2021-09-05
  • 1970-01-01
  • 2020-06-14
  • 2019-07-03
  • 2018-01-17
  • 1970-01-01
相关资源
最近更新 更多