首页 > 解决方案 > Reactjs如何在相同的html代码中显示来自嵌套json对象的数据

问题描述

我的应用程序同时从两个 api 端点获取数据,并将数据组合成一个嵌套的 json 对象,如下所示:

{
"Shop1": [
  {
    "product_name": "Shop 1 Wine", 
    "product_price": "4.99"
  }, 
  {
    "product_name": "Shop1 Wine 2", 
    "product_price": "4.49"
  }
],
"Shop2": [
  {
    "product_name": "Shop 2 Wine", 
    "product_price": "4.99"
  }, 
  {
    "product_name": "Shop 2 Wine 2", 
    "product_price": "4.49"
  }
 ]
}

这就是 reactjs 获取数据的方式:

function App() {



const ListLoading = withListLoading(List);
  const [appState, setAppState] = useState({
    loading: false,
    products: null,
  });

  useEffect(() => {
    setAppState({ loading: true });
    const baseUrl = "http://localhost:8080/"
    const searchItem = "wine"
    const shops = [
      "Shop1",
      "Shop2"
    ];
    let urls = [];

    const allUrls = shops.map((shop) => {
      let url = baseUrl + shop + "/" + searchItem;
      urls.push(url)
    });

    function fetchData() {
      const allRequests = urls.map(url =>
        fetch(url).then(response => response.json())
      );
      return Promise.all(allRequests);
    };

    fetchData().then(arrayOfResponses => 
      setAppState({loading: false, products: arrayOfResponses})
    );
  }, [setAppState]);
  return (
    <div className='App'>
      <div className='container'>
        <h1>Products</h1>
      </div>
      <div className='repo-container'>
        <ListLoading isLoading={appState.loading} products={appState.products} />
      </div>
      <footer>
      </footer>
    </div>
  );
}
export default App;

然后在实际页面中我有这个:

import React from 'react';
const List = (props) => {
  const { products } = props;
  if (!products || products.length === 0) return <p>No products, sorry</p>;
  return (
    <ul>
      <h1>{products}</h1>
      <h2 className='list-head'>products</h2>
      {products.map((product) => {
        return (
          <li className='list'>
            <span className='{product.shop_name}'>{product.product_name} </span>
            <span className='repo-description'>{product.product_price}</span>
          </li>
        );
      })}
    </ul>
  );
};
export default List;

我希望能够遍历 json 对象中的每个元素并product.shop_name代替顶级值(如 shop1 或 shop2),然后在 span 中阻止与给定商店相关的值(如 product_name 和 product_price)。

目前我收到以下错误:

Error: Objects are not valid as a React child (found: object with keys {Shop1}). If you meant to render a collection of children, use an array instead..

如何对循环遍历每个级别 1 值做出反应,然后对级别 2 值执行相同操作并在 html 中显示它们?

标签: javascriptarraysjsonreactjs

解决方案


来自您的州产品。您需要先获取密钥,因为此产品不是数组而是 json 对象。

所以在你的渲染中

return(
 <div>
   <h1>Shop1</h1>
     {products.Shop1.map((item,index)=>
        <span>{item.product_name} </span>
        <span>{item.product_price}</span>
     )}

    <h1>Shop2</h1>
    {products.Shop2.map((item,index)=>
       <div key={index}>
          <span>{item.product_name} </span>
          <span>{item.product_price}</span>
       </div>
    )}
  </div>
)

否则,您将需要将数据检索到数组中

IE

[
"Shop1": [
  {
    "product_name": "Shop 1 Wine", 
    "product_price": "4.99"
  }, 
  {
    "product_name": "Shop1 Wine 2", 
    "product_price": "4.49"
  }
],
"Shop2": [
  {
    "product_name": "Shop 2 Wine", 
    "product_price": "4.99"
  }, 
  {
    "product_name": "Shop 2 Wine 2", 
    "product_price": "4.49"
  }
 ]
]

所以你会做

return(
 <div>
     {shops.map((shop,index)=>
        <div>
           <h1>{shop.name}</h1>
            {shop.products.map((product,pos)=>
               <div key={pos}>
                 <span>{product.product_name} </span>
                 <span>{product.product_price}</span>
               </div>
             }
         </div>
     )}
  </div>
)

推荐阅读