简体   繁体   English

如何在 React 中正确使用 async/await 和 Array.filter?

[英]How do I use async/await with Array.filter properly in React?

I'm creating just a simple currency converter (React + Typescript).我正在创建一个简单的货币转换器(React + Typescript)。 Here is my component code:这是我的组件代码:

const App = () => {

  const [countries, setCountries] = useState<Array<CountriesProps>>([])
  const [currencies, setCurrencies] = useState<Currencies>({})
  
  const filteredCountries = async () => {
      const { data } = await axios.get('https://restcountries.eu/rest/v2/all')
      const answer: Array<CountriesProps> = data
      const filtered = answer.filter(country => {
        for (let i in currencies) {
          if(i === country.currencies[0].code) {
            return country
          }
        }
      })
      setCountries(filtered)
  }
  
  useEffect(() => {
    axios
      .get('https://api.frankfurter.app/currencies')
      .then(res => {
        setCurrencies(res.data)
      })
      .catch(err => {
        console.log(err)
      }) 
  }, [])

  useEffect(() => {
    filteredCountries()
  }, [])

  return (
    ...
  )
}

export default App

I come across the problem, during launching the app.我在启动应用程序时遇到了问题。 After getting currencies information from the server I need to fetch countries information.从服务器获取货币信息后,我需要获取国家信息。 After getting countries I need to filter them and put them in my state (countries) and send it to another component and so on.获得国家后,我需要过滤它们并将它们放入我的 state(国家)并将其发送到另一个组件等等。 But during launch of the app filter function doesn't work and I got no filtered countries and so I don't have any info in my state.但是在启动应用程序过滤器 function 期间不起作用,我没有过滤国家,所以我的 state 中没有任何信息。 I think that filter function needs to be an asynchronous, so we need to wait before setting our state through setCountries function.我认为过滤器 function 需要是异步的,所以在通过 setCountries function 设置我们的 state 之前需要等待。 How to do it properly in my case or I did all the logic wrong?在我的情况下如何正确地做到这一点,或者我做错了所有的逻辑?

As long as requested countries rely on fetched currencies and you don't seem to be using one without the another, you may stack .get() -requests accordingly or use respective async...await alternative:只要被请求的国家/地区依赖于获取的货币,并且您似乎没有在没有使用另一种的情况下使用一种货币,您就可以相应地堆叠.get() -requests 或使用相应的async...await替代方案:

fetchData = async () => {
      const currenciesResponse = await axios.get(currenciesEndpoint),
        currenciesData = await currenciesResponse.data,
        countriesResponse = await axios.get(countriesEndpoint),
        countriesData = await countriesResponse.data,
        filteredCountriesData = countriesData.filter(_country => {
          const {
            currencies: [{ code }]
          } = _country;
          return currenciesData[code];
        });
      setCurrencies(currenciesData);
      setCountries(filteredCountriesData);
    }

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

Following is a full-blown demo as a proof-of-a-concept以下是作为概念验证的完整演示

See if this helps.看看这是否有帮助。

const [countries, setCountries] = useState<Array<CountriesProps>>([])
  const [currencies, setCurrencies] = useState<Currencies>({})
  
  const filteredCountries = async () => {
      const { data } = await axios.get('https://restcountries.eu/rest/v2/all')
      const answer: Array<CountriesProps> = data
      const filtered = answer.filter(country => {
        return currencies[country.currencies[0].code]
      })
      setCountries(filtered)
  }
  
  useEffect(() => {
    axios
      .get('https://api.frankfurter.app/currencies')
      .then(res => {
        setCurrencies(res.data)
      })
      .catch(err => {
        console.log(err)
      }) 
  }, [])

  useEffect(() => {
    filteredCountries()
  }, [currencies])

try using this:尝试使用这个:


const App = () => {

  const [countries, setCountries] = useState<Array<CountriesProps>>([])
  const [currencies, setCurrencies] = useState<Currencies>({})
  
  const filteredCountries = async () => {
      const res = await axios.get('https://api.frankfurter.app/currencies')
      // you don't need a state for currencies but in case you find a use case for it,
      // you're just setting the currencies here for future use cases.
      setCurrencies(res.data);
      const { data } = await axios.get('https://restcountries.eu/rest/v2/all')
      const answer: Array<CountriesProps> = data
      const filtered = answer.filter(country => {
        for (let i in res.data) {
          if(i === country.currencies[0].code) {
            return country
          }
        }
      })
      setCountries(filtered)
  }

  useEffect(() => {
    filteredCountries()
  }, [])

  return (
    ...
  )
}

export default App

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM