繁体   English   中英

(反应)当我从 API 获取一些数据时,如何阻止我的 web 应用程序重新渲染?

[英](React) How can I stop my web app from re-rendering when I fetch some data from an API?

I made a web app that fetches and displays information about random countries using the REST countries API ( https://restcountries.eu/ ). 让我烦恼并且我不明白为什么会发生的事情(我一直在反复运行代码并且我没有看到问题)是当我按下“新国家”按钮时,我看到它显示简述一个国家,然后重新渲染App,并带上另一个国家。 这更令人讨厌,但我想修复它,因为它不是很顺利。 想法? 谢谢!

import React, {useState, useEffect} from "react"

function CountryInfo() {
    const [loading, setLoading] = useState(true)
    const [countryName, setCountryName] = useState("")
    const [countryCapital, setCountryCapital] = useState("")
    const [countryPopulation, setCountryPopulation] = useState(0)
    const [countryRegion, setCountryRegion] = useState("")
    const [countrySubRegion, setCountrySubRegion] = useState("")
    const [countryArea, setCountryArea] = useState(0)
    const [countryFlag, setCountryFlag] = useState("")
    

    function fetchData() {
        fetch("https://restcountries.eu/rest/v2/all")
            .then(response => response.json())
            .then(data => {
                var randomCountry = Math.floor(Math.random() * (data.length - 1) + 1)
                setLoading(false)
                setCountryName(data[randomCountry].name)
                setCountryCapital(data[randomCountry].capital)
                setCountryPopulation(data[randomCountry].population)
                setCountryArea(data[randomCountry].area)
                setCountryRegion(data[randomCountry].region)
                setCountrySubRegion(data[randomCountry].subregion)
                setCountryFlag(data[randomCountry].flag)
            })
    }

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

    return (
        <div className="country-info">
            <div style={{display: loading? 'block' : 'none'}}><p>Loading...Please wait</p></div>
            <div style={{display: loading? 'none' : 'block'}}>
                <h1>Random Country: {countryName}</h1>
                <hr />
                <p>Let's get some facts!</p>
                <p>Capital: {countryCapital}</p>
                <p>Population: {countryPopulation}</p>
                <p>Region: {countryRegion}</p>
                <p>Sub-region: {countrySubRegion}</p>
                <p>Area: {countryArea} km</p>
            </div>
            <img src={countryFlag}></img>
            <form onSubmit={fetchData}><button>New Country</button></form>
        </div>
    )
}

export default CountryInfo

为了正确呈现您的组件并在调用 api 期间发生任何事情时捕获错误,请避免使用 boolean 类型进行加载并使用字符串来描述状态。 我对你的代码做了一些修改:

import React, {useState, useEffect} from "react"

function CountryInfo() {
    const [loading, setLoading] = useState('idle');
    const [error, setError] = useState('');

    const [country, setCountry] = useState({
      name: '',
      capital: '',
      population: 0,
      region: '',
      subregion: '',
      area: 0,
      flag: ''
    })
    

    function fetchData() {
        setLoading('pending');
        fetch("https://restcountries.eu/rest/v2/all")
            .then(response => response.json())
            .then(data => {
                var randomCountry = Math.floor(Math.random() * (data.length - 1) + 1)
                setCountry(data[randomCountry]);
                setLoading('resolved')
            })
            .catch((error) => {
              setLoading('rejected');
              setError(error);
            })
    }

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

    let content;
    if (loading === 'pending' || loading === 'idle') {
      content = <h1>...Loading</h1>
    } else if (loading === 'rejected') {
      content = <div>
      <div>Oops an error occured:</div>
      <pre>{error.message}</pre>
      </div>
    } else {
      content = (
        <div className="country-info">
            <div style={{display: 'block'}}>
                <h1>Random Country: {country.name}</h1>
                <hr />
                <p>Let's get some facts!</p>
                <p>Capital: {country.capital}</p>
                <p>Population: {country.population}</p>
                <p>Region: {country.region}</p>
                <p>Sub-region: {country.subregion}</p>
                <p>Area: {country.area} km</p>
            </div>
            <img alt='countryFlag' src={country.flag}></img>
            <form onSubmit={fetchData}><button>New Country</button></form>
        </div>
    )
    }

    return content;
}

export default CountryInfo;

有关更多信息,请查看此链接Stop using isLoading booleans

暂无
暂无

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

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