【问题标题】:React state not displaying appropriately反应状态未正确显示
【发布时间】:2021-11-14 16:51:47
【问题描述】:

我的问题:我的状态有时会显示,如果我刷新浏览器,更新代码我收到以下错误 TypeError: Cannot read properties of undefined (reading 'country') 我不确定为什么会发生这种行为。在一种情况下它会显示,而另一种情况下它不会。任何解释和解决方案将不胜感激。

我的响应返回 200 状态代码,并且我 console.log 中的所有适当数据都是合法的,所以我很困惑为什么会出现这个问题。


App.js

import api from './api/fetchCovidData'
import { useState, useEffect } from 'react'

const  App = () => {
  const [covid, setCovidData] = useState({})

  useEffect(() => {
    const fetchCovidData = async () => {
      try{
        const response = await api.get('/cases?country=France');
        console.log(response.data)
        setCovidData(response.data);
      } catch (err) {
        if (err.response){
          // Not in the 200 response range
          console.log(err.response.data);
          console.log(err.response.status);
          console.log(err.response.headers);
        } else {
          console.log(`Error: ${err.message}`);
        }
      }
    }
    fetchCovidData();
  }, []);

  return (
    <div>
      <h1>{covid.All.country}</h1>
      <h1>{covid.All.population}</h1>
    </div>
  );
}

export default App;

fetchCovidData.js

import axios from "axios";

export default axios.create({
    baseURL: 'https://covid-api.mmediagroup.fr/v1'
});

示例响应

{
  "All": {
    "confirmed": 2604595,
    "recovered": 195365,
    "deaths": 62548,
    "country": "France",
    "population": 64979548,
    "sq_km_area": 551500,
    "life_expectancy": "78.8",
    "elevation_in_meters": 375,
    "continent": "Europe",
    "abbreviation": "FR",
    "location": "Western Europe",
    "iso": 250,
    "capital_city": "Paris",
    "lat": "46.2276",
    "long": "2.2137",
    "updated": "2020/12/26 12:21:56+00"
  }
}

【问题讨论】:

    标签: javascript reactjs json axios


    【解决方案1】:

    问题

    这里的问题是你的初始状态是一个空对象:

    const [covid, setCovidData] = useState({});
    

    但您试图在初始渲染您的状态真正填充之前引用太深的级别:

    <div>
      <h1>{covid.All.country}</h1>
      <h1>{covid.All.population}</h1>
    </div>
    

    这里covid 是空对象({}),访问covid.All 是可以的,因为它返回undefined,但是当您尝试访问covid.All.country 时,现在您正在尝试访问未定义对象的属性并引发错误(TypeError: Cannot read properties of undefined (reading 'country'))。

    解决方案

    1. 提供有效的初始状态

      const [covid, setCovidData] = useState({ All: {} });   
      
    2. 使用Optional Chaining operator 处理空检查

      <div>
        <h1>{covid.All?.country}</h1>
        <h1>{covid.All?.population}</h1>
      </div>
      
    3. 使用传统的空检查/保护子句

      <div>
        <h1>{covid.All && covid.All.country}</h1>
        <h1>{covid.All && covid.All.population}</h1>
      </div>
      
    4. 使用条件渲染

      <div>
        {covid.All && (
          <h1>{covid.All.country}</h1>
          <h1>{covid.All.population}</h1>
        )}
      </div>
      

    【讨论】:

      【解决方案2】:

      问题是您的初始状态为空。所以,你必须在使用前检查状态是否为空/未定义/空。

      return (
          covid && covid.All && (<div>
            <h1>{covid.All.country}</h1>
            <h1>{covid.All.population}</h1>
          </div>)
        )
      

      <div>
         <h1>{covid?.All?.country}</h1>
         <h1>{covid?.All?.population}</h1>
      </div>
      

      【讨论】:

        【解决方案3】:

        尝试添加问号以验证是否存在 {covid?.All?.country} 另一种选择是设置条件

        return (
                covid && (<div>
                  <h1>{covid?.All?.country}</h1>
                  <h1>{covid?.All?.population}</h1>
                </div>)
              )
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

        import api from './api/fetchCovidData'
        import { useState, useEffect } from 'react'
        
        const  App = () => {
          const [covid, setCovidData] = useState({})
        
          useEffect(() => {
            const fetchCovidData = async () => {
              try{
                const response = await api.get('/cases?country=France');
                console.log(response.data)
                setCovidData(response.data);
              } catch (err) {
                if (err.response){
                  // Not in the 200 response range
                  console.log(err.response.data);
                  console.log(err.response.status);
                  console.log(err.response.headers);
                } else {
                  console.log(`Error: ${err.message}`);
                }
              }
            }
            fetchCovidData();
          }, []);
        
          return (
            <div>
              <h1>{covid?.All?.country}</h1>
              <h1>{covid?.All?.population}</h1>
            </div>
          );
        }
        
        export default App;
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-12-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-01
          • 2017-03-14
          • 1970-01-01
          相关资源
          最近更新 更多