【问题标题】:Issue mapping an array from api fetch call从 api fetch 调用映射数组的问题
【发布时间】:2020-10-22 11:09:26
【问题描述】:

我查看了以前的帖子,没有看到任何解决此问题的内容。我正在使用功能组件/挂钩从开源 api 获取数据。只要我在返回渲染中仅显示 data.map 中的 1 个字段,该代码就可以工作。如果我尝试显示多个,我会收到以下错误:Objects are not valid as a React child (found: object with keys {name, catchPhrase,bs})。如果您打算渲染一组子项,请改用数组。 DevTools 表示错误在列表组件中。当除一个列表元素之外的所有元素都被注释掉时,我可以看到在 DevTools 中返回了整个数组,并且将显示一个列表元素。添加其他字段(列表项)会导致错误。不知道我做错了什么。任何帮助表示赞赏。

import React, { useEffect, useState } from 'react';

function PeopleData() {
  const [data, setData] = useState([]);

      function GetData(){
      fetch('https://jsonplaceholder.typicode.com/users')
        .then(response => response.json())
        .then(response => setData(response))

      }
      console.log(data) 

      useEffect(() => {
        GetData();
      }, []);
      
  return (
    <div>
      {data.map(item => <div key={item.id}>
        <div>
          <li>{item.name}</li>
          {/* <li>{item.company}</li>
          <li>{item.phone}</li>
          <li>{item.email}</li> */}
        </div>
      </div>)}
    </div>
  )
}
export default PeopleData;

【问题讨论】:

  • item.company 是一个对象
  • @Ron 请为您认为有用的任何答案投票

标签: json reactjs dictionary


【解决方案1】:

Item.company 是一个对象,这就是 React 抛出错误的原因。您必须访问公司的属性。如果您想显示公司的所有属性,您可以构建一个“For In”循环并同时显示它们。如果您需要说明,我可以给您举个例子。

作为一个小提示和提示,请查看 useFetch 钩子。你会喜欢它的,尤其是当你有多个组件来获取这样的数据时。

【讨论】:

    【解决方案2】:

    company 属性是一个对象,并且一个对象不能是 React 中的子对象,正如它在错误中所说的那样。

    对象作为 React 子对象无效(找到:带键的对象 {name, 流行语,bs})

    解决方案是只显示公司对象中您可能有兴趣在 UI 中显示的属性。

    import React, { useEffect, useState } from 'react';
    
    function PeopleData() {
      const [data, setData] = useState([]);
    
          function GetData(){
          fetch('https://jsonplaceholder.typicode.com/users')
            .then(response => response.json())
            .then(response => setData(response))
    
          }
          console.log(data) 
    
          useEffect(() => {
            GetData();
          }, []);
          
      return (
        <div>
          {data.map(item => <div key={item.id}>
            <div>
              <li>{`Name: ${item.name}`}</li>
              <li>{`Company: ${item.company.name}`}</li>
              <li>{`Phone: ${item.phone}`}</li>
              <li>{`Email: ${item.email}`}</li>
            </div>
          </div>)}
        </div>
      )
    }
    export default PeopleData;
    

    【讨论】:

      【解决方案3】:

      每个对象都具有如下所示的形状,并且应用程序崩溃了,因为您尝试渲染作为对象的company,而它需要一个字符串或节点。所以你应该改用item.company.name

      
      {
        id: 1,
        name: "Leanne Graham",
        ...
        company: {
          name: "Romaguera-Crona",
          catchPhrase: "Multi-layered client-server neural-net",
          bs: "harness real-time e-markets",
        },
      };
      

      您还可以利用 await/async 语法,而不是将下面的 then 语句链接在一起。通过 await 操作符承诺在下一行开始之前执行该行

       async function GetData() {
          const response = await fetch("https://jsonplaceholder.typicode.com/users");
          const json = await response.json();
          setData(json);
        }
      

      我在https://codesandbox.io/s/throbbing-butterfly-dt2yy?file=/src/App.jshttps://codesandbox.io/s/throbbing-butterfly-dt2yy?file=/src/App.js的沙盒中工作

      【讨论】:

        【解决方案4】:

        这是因为您试图从响应中显示company 属性。

        来自 API:

        "company": {
          "name": "Romaguera-Crona",
          "catchPhrase": "Multi-layered client-server neural-net",
          "bs": "harness real-time e-markets"
        }
        

        这意味着您必须显示company.namecompany.bscompany.catchPhrase

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-17
          • 2020-06-29
          • 2017-12-18
          • 2016-02-17
          • 2017-09-23
          • 2017-01-11
          相关资源
          最近更新 更多