简体   繁体   English

处理 React useEffect 钩子中的响应状态 - 生命周期问题?

[英]Handling response status in React useEffect hook - lifecycle issue?

I'm currently rendering some data by fetching from API within the useEffect hook.我目前正在通过从useEffect钩子中的 API 获取来呈现一些数据。

I have a searchValue variable which holds the value the user inputs on the home page search field.我有一个searchValue变量,它保存用户在主页搜索字段上输入的值。 This is passed down to this component .这将传递给该component

I have set searchValue in the useEffect dependencies so that when it changes it will run the effect again.我在useEffect依赖项中设置了searchValue以便当它改变时它会再次运行效果。

When it mounts, it seems to be skipping the !res.ok if statement.当它安装时,它似乎跳过了!res.ok if 语句。 I have logged the res.ok to the console outside of this if statement and with each character inputted into the searchValue it always comes back true .我已将res.ok记录到此 if 语句之外的控制台,并且输入到searchValue每个字符总是返回true The response status is always 200 after a character press so it never runs the !res.ok if statement block.按下字符后,响应状态始终为 200,因此它永远不会运行!res.ok if 语句块。 Something must be wrong with my understanding of the lifecycle or asynchronous calls.我对生命周期或异步调用的理解一定有问题。

I am getting the error: countriesData.map is not a function - so it is trying to render the map on invalid data however this should not even return since I have if (error) written first within the Content function.我收到错误: countriesData.map is not a function - 所以它试图在无效数据上呈现map ,但是这甚至不应该返回,因为我首先在Content函数中写入了if (error) If this is matched it should return the error message instead, but this is skipped and the countriesData is updated with invalid data.如果匹配,它应该返回错误信息,而不是,但这个被跳过, countriesData与无效数据更新。 My code is below, please help!我的代码在下面,请帮忙! I feel like I'm missing something simple and misunderstanding some fundamentals of React!我觉得我错过了一些简单的东西并且误解了 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

I think you must be mistaken about the shape of countriesData .我认为您一定对countriesData的形状有误解。 You initialise it to an empty array, so .map will work on that.您将其初始化为一个空数组,因此.map将适用.map Then the only place you change it is setCountriesData(data) - so this must not be an array.然后你唯一改变它的地方是setCountriesData(data) - 所以这不能是一个数组。

If you are sure that you are setting array to countriesData, then you can fix by just adding Optional chaining syntax.如果您确定将数组设置为 countryData,那么您只需添加 Optional 链接语法即可修复。

replace countriesData.map with更换countriesData.map

countriesData?.map

Optional chaining 可选链

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

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