开发者问题收集

反应错误‘无法读取未定义的属性(读取‘map’)’

2022-08-21
9522

因此,在我的代码中,setData 似乎工作正常,并将获取的数据提供给我的状态。但是它在第一次渲染时不起作用。但如果我在代码中更改某些内容,网站将再次渲染,国家名称将按照我想要的方式显示在屏幕上。

但此错误不断弹出: 未捕获的类型错误:无法读取未定义的属性(读取“common”)

import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';

function Country() {
  const { countryName } = useParams();
  const [data, setData] = useState([]);
  const [country, setCountry] = useState({});

  useEffect(() => {
    fetch('https://restcountries.com/v3.1/all')
      .then(resp => resp.json())
      .then(datas => setData(datas));
  }, [])

  useEffect(() => {
    setCountry(data.find(a => a.name.common.toLowerCase() == countryName.replaceAll("-", " ")));
  }, [data])

  return (
    <>
      {
        <h1>{country.name.common}</h1>
      }
    </>
  )
}

export default Country
<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>
3个回答

这意味着 country.nameundefined (而不是具有 common 属性的对象)。

在初始渲染时, country{}(一个空对象)。

因此, country.name 返回 undefined。

并且 undefined 没有 common 属性。因此,出现错误。

因此,在访问属性之前,一个好的经验法则是检查该属性是否存在。

<h1>{country?.name?.common}</h1>

大多数情况下,如果没有数据,您不想显示标签。

因此,您想做这样的事情。

仅当 && 之后的标记之前的表达式为真值时,才会呈现该标记。

{country?.name?.common && (
 <h1>{country.name.common}</h1>
)}
Jashwant
2022-08-21

由于 country 的初始值是一个空对象, name 属性将未定义,从而导致此错误,您只需为 name 设置一个初始值,作为一个空的 对象

const [country, setCountry] = useState({ name: {} });

完整代码示例。

import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';

function Country() {
  const { countryName } = useParams();
  const [data, setData] = useState([]);
  const [country, setCountry] = useState({ name: {} });

  useEffect(() => {
    fetch('https://restcountries.com/v3.1/all')
      .then(resp => resp.json())
      .then(datas => setData(datas));
  }, [])

  useEffect(() => {
    setCountry(data.find(a => a.name.common.toLowerCase() == countryName.replaceAll("-", " ")));
  }, [data])

  return (
    <>
      {
        <h1>{country.name.common}</h1>
      }
    </>
  )
}

export default Country

或者您可以选择链接 name 属性。

<h1>{country.name?.common}</h1>
Mina
2022-08-21

我在 Chrome 中打开了一个新标签页并粘贴您的 api https://restcountries.com/v3.1/all ,从网络选项卡中,结果有一些奇怪的对象没有“name”:{“common”....。

您必须过滤掉这些对象

在此处输入图像描述

Tran Loc
2022-08-21