【问题标题】:Handling response status in React useEffect hook - lifecycle issue?处理 React useEffect 挂钩中的响应状态 - 生命周期问题?
【发布时间】:2021-12-20 17:32:02
【问题描述】:

我目前正在通过从 useEffect 挂钩中的 API 获取来呈现一些数据。

我有一个searchValue 变量,它保存用户在主页搜索字段中输入的值。这被传递给这个component

我在useEffect 依赖项中设置了searchValue,这样当它发生变化时,它会再次运行效果。

当它挂载时,它似乎正在跳过!res.ok if 语句。我已将res.ok 记录到此 if 语句之外的控制台,并且每个字符输入到searchValue 中,它总是返回true。按下字符后响应状态始终为 200,因此它永远不会运行 !res.ok if 语句块。我对生命周期或异步调用的理解一定有问题。

我收到错误:countriesData.map is not a function - 所以它试图在无效数据上渲染map,但这甚至不应该返回,因为我首先在Content 函数中写入了if (error)。如果匹配,则应返回错误消息,但会跳过此消息,并使用无效数据更新 countriesData。我的代码如下,请帮忙!我觉得我遗漏了一些简单的东西并且误解了 React 的一些基础知识!

import { useEffect, useState } from 'react'
import CountryCard from '../CountryCard'
import { countries } from './CountriesList.module.css'

const CountriesList = ({ searchValue }) => {
    const [error, setError] = useState(false)
    const [loading, setLoading] = useState(true)
    const [countriesData, setCountriesData] = useState([])

    useEffect(() => {
        const getCountries = async () => {
            let res = await fetch('https://restcountries.com/v2/all')
            if (searchValue !== '') {
                res = await fetch(
                    `https://restcountries.com/v2/name/${searchValue}`
                )
            }

            if (!res.ok) {
                console.log(res)
                return setError(true)
            }

            const data = await res.json()
            setCountriesData(data)
            setLoading(false)
        }

        getCountries()

        // return () => setLoading(true)
    }, [searchValue])

    const Content = () => {
        if (error) {
            return <div>Error: please check the country you have typed</div>
        }

        if (loading) {
            return <div>Loading...</div>
        }

        return (
            <section className={`${countries} columns is-multiline`}>
                {countriesData.map((country) => (
                    <CountryCard {...country} key={country.name} />
                ))}
            </section>
        )
    }

    return <Content />
}

export default CountriesList

【问题讨论】:

    标签: javascript reactjs async-await fetch react-lifecycle


    【解决方案1】:

    我想你一定对countriesData的形状有误解。您将其初始化为一个空数组,因此.map 将对其进行处理。那么你唯一改变它的地方是setCountriesData(data) - 所以这不能是一个数组。

    【讨论】:

    • 啊,是的,甚至没有考虑过欢呼声。看起来当使用不正确的名称时,API 返回一个对象,而当它有效时,它返回一个对象数组。
    • 这就是问题所在。已修复并解决,甚至没有考虑检查 API 返回的内容。菜鸟失误
    【解决方案2】:

    如果您确定将数组设置为国家数据,则只需添加可选链接语法即可修复。

    countriesData.map替换为

    countriesData?.map
    

    Optional chaining

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-19
      • 2019-09-23
      • 2019-05-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多