简体   繁体   English

如何在 React 中映射 JSON 响应

[英]How to map over a JSON response in React

Hi I'm trying to learn how to use React with an API response.嗨,我正在尝试学习如何将 React 与 API 响应一起使用。 I have a GraphQL API endpoint that is returning information on products in JSON.我有一个 GraphQL API 端点,它以 JSON 格式返回有关产品的信息。 I would like to loop over the response and render a react component for each product simply displaying the product name.我想循环响应并为每个产品渲染一个反应组件,只需显示产品名称。

The JSON response looks like this: JSON 响应如下所示:

{
  "data": {
    "products": [
      {
        "productName": "Pepsi",
        "price": "1.99",
      },
      {
        "productName": "Coke",
        "price": "2.99",
      },
      // and so on...
    ]
  }
}  

I've successfully console logged each product name by doing the following (I'm using axios):我通过执行以下操作成功地控制台记录了每个产品名称(我正在使用 axios):

async function contactAPI() {
  return await axios({
    url: 'https://graphqlexample.com/api/products',
    method: 'post',
    data: {
      query: `
        QUERY GOES HERE
          `
    }
  })
}

async function goFetch() {
  let resp = await contactAPI();
  for (let entry in resp.data.data.products) {
    console.log(resp.data.data.products[entry]['productName']);
  }  
}

But now I would like to render a react component for each product, but I keep getting the error Objects are not valid as a React child (found: [object Promise]).但是现在我想为每个产品渲染一个Objects are not valid as a React child (found: [object Promise]).组件,但我不断收到错误Objects are not valid as a React child (found: [object Promise]). Below is the code I'm using right now.下面是我现在使用的代码。 How can I fix this so that I can return a react component for each product with the product name?我该如何解决这个问题,以便我可以为每个产品返回一个带有产品名称的反应组件?

App.js应用程序.js

async function contactAPI() {
  return await axios({
    url: 'https://graphqlexample.com/api/products',
    method: 'post',
    data: {
      query: `
        QUERY GOES HERE
          `
    }
  })
}

async function App() {
  let resp = await contactAPI();
  return (
    <div>
      {resp.map(p => (
        <div>
          <ProductCard productName={p.productName} />
        </div>
      ))}
    </div>
  );
}

ProductCard.js产品卡片.js

function ProductCard(props) {
  return (
    <div>
      <div>{props.productName}</div>      
    </div>
  );
}

Edit: Based on Andy's suggestion, I tried using states and useEffect, but I'm getting two errors.编辑:根据安迪的建议,我尝试使用状态和 useEffect,但出现两个错误。 The first one is Error: Objects are not valid as a React child (found: [object Promise]).第一个是Error: Objects are not valid as a React child (found: [object Promise]). and the second one is Unhandled Rejection (Error): Invalid hook call. Hooks can only be called inside of the body of a function component.第二个是Unhandled Rejection (Error): Invalid hook call. Hooks can only be called inside of the body of a function component. Unhandled Rejection (Error): Invalid hook call. Hooks can only be called inside of the body of a function component. The second error points to const [products, setProducts] = useState([]);第二个错误指​​向const [products, setProducts] = useState([]);

This is my current code:这是我当前的代码:

async function App() {
  const [products, setProducts] = useState([]);

  useEffect(() => {
    async function getData() {
      const res = await contactAPI();
      setProducts(res.data.data.products);
    }
    getData();
  }, []);

  return (
    <div>
      <div>
        {products.map(p => (
          <div>
            <ProductCard productName={p.productName} />
          </div>
        ))}
      </div>
    </div>
  );
}

Edit 2: Fixed by removing the async keyword from the original function App()编辑 2:通过从原始函数App()删除async关键字来修复

Since you're using functional components you should implement hooks to 1) get the data, and 2) manage the component state.由于您使用的是功能组件,因此您应该实现挂钩以 1) 获取数据,以及 2) 管理组件状态。 useEffect to get the data on first render, and useState to store and manage the data that's returned. useEffect在第一次渲染时获取数据,并useState存储和管理返回的数据。 You can then map over that data stored in the state to create the JSX.然后,您可以map存储在状态中的数据以创建 JSX。

const { useEffect, useState } = React;

function App() {

  // Initialise the state with an empty array
  const [products, setProducts] = useState([]);
  
  // Call `useEffect` with an empty dependency array
  // which will ensure it runs only once
  useEffect(() => {

    // Call the contactAPI function, wait for
    // the data and then update the state with the
    // product array
    async function getData() {
      const res = await contactAPI();
      setProducts(res.data.data.products);
    }
    getData();
  }, []);

  // If the state array is empty show a simple message
  if (!data.length) return <div>No data</div>;

  // Otherwise `map` over the state and produce the JSX
  return (
    <div>
      {products.map(product => (
        <div>
          <ProductCard productName={product.productName} />
        </div>
      ))}
    </div>
  );
}

To display the JSON data in React i have used 2 methods.为了在 React 中显示 JSON 数据,我使用了 2 种方法。 1.You can make use of class component for fetch it as api. 1.您可以使用类组件将其作为api获取。 2.You can import the JSON data file and simply map it. 2.您可以导入JSON数据文件并简单地映射它。

This is my way of displaying JSON data on React applicatons.这是我在 React 应用程序上显示 JSON 数据的方式。

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

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