【问题标题】:Displying nested Json data in ReactJS在 React JS 中显示嵌套的 Json 数据
【发布时间】:2021-06-13 15:55:23
【问题描述】:

我正在尝试获取 JSON 的嵌套数据,但始终显示“无法读取未定义的属性 'map'”。我已经看过关于这个问题的教程,但似乎总是出现错误。

问题来了,在这段代码中,我想显示配料的嵌套数据然后我不知道我对地图的语法是否错误,但我看了教程,地图的放置是正确的。

<div>
  {recipes.title}
    <ul>
      {recipes.ingredients.map((sub) => (
      <li>{sub.ingredients}</li>
      ))}
    </ul>
</div>

这是整体代码

//JSON DATA
[
    {
       "uuid":"e80ea521-4d42-48fe-a7a6-ac8952bc0de4",
       "title":"Queso Brat Scramble",
       "description":"A delicious breakfast, fit for a crowd.",
       "images":{
          "full":"/img/queso_brat_scramble.jpg",
          "medium":"/img/queso_brat_scramble--m.jpg",
          "small":"/img/queso_brat_scramble--s.jpg"
       },
       "servings":5,
       "prepTime":10,
       "cookTime":20,
       "postDate":"01/20/2018 05:15:03 PM",
       "editDate":"02/05/2018 11:56:29 PM",
       "ingredients":[
          {
             "uuid":"62798278-2fbc-4c31-98de-b7959c191688",
             "amount":1,
             "measurement":"package (19 oz)",
             "name":"queso brats"
          },
          {
             "uuid":"2df619ea-8472-48f4-9615-3f387a492d22",
             "amount":8,
             "measurement":"tablespoons",
             "name":"canola oil"
          },
       ]
    },
 ]

//React CODE
import { useHistory, useParams } from "react-router";
import React, { useState, useEffect } from "react";
import api from "../Api/Recipes";
import DatePosted from "./DatePosted";
import "./ViewRecipe.css";

const ViewRecipe = () => {
  const baseURL = "http://localhost:3001";
  const { id } = useParams();
  const retriveRecipes = async () => {
    const response = await api.get("/recipes/" + id);
    return response.data;
  };

  const [recipes, setRecipes] = useState([]);

  useEffect(() => {
    const getAllRecipes = async () => {
      const allRecipes = await retriveRecipes();
      if (allRecipes) setRecipes(allRecipes);
    };

    getAllRecipes();
  }, []);

  useEffect(() => {}, [recipes, recipes.images]);

  return (
    <div>
      {recipes && (
        <div className="blog-content">
          <div>
            <DatePosted datePosted={new Date(recipes.postDate)} />
          </div>
          <h2>{recipes.title}</h2>
          <p>{recipes.description}</p>
          <div className="legends">
            <div>
              <span className="badge">
                <i className="fas fa-clock"></i> Cook Time: {recipes.cookTime}{" "}
                mins
              </span>
            </div>
            <div>
              <span className="badge">
                <i className="fas fa-clock"></i> Preperation Time:{" "}
                {recipes.prepTime} mins
              </span>
            </div>
            <div>
              <span className="badge">
                <i className="fas fa-utensils"></i> Servings: {recipes.servings}
                mins
              </span>
            </div>
          </div>
          <hr />

          <h5>Images</h5>
          <ul>{recipes.images && <li>{recipes.images.full}</li>}</ul>
          <ul>{recipes.images && <li>{recipes.images.medium}</li>}</ul>
          <ul>{recipes.images && <li>{recipes.images.small}</li>}</ul>
          <h5>Ingredients</h5>
          <div>
            {recipes.title}
            <ul>
              {recipes.ingredients.map((sub) => (
                <li>{sub.ingredients}</li>
              ))}
            </ul>
          </div>
        </div>
      )}
    </div>
  );
};

export default ViewRecipe;

【问题讨论】:

  • recipes.ingredientsundefined,因为 recipesarray 而不是 Object
  • 您好,谢谢您,先生,我想请教一下如何解决这个问题?我是 React 新手

标签: json reactjs nested


【解决方案1】:

所以你遇到的问题是由于反应如何渲染和重新渲染状态。

 const [recipes, setRecipes] = useState([]);

您正在正确初始化它,这很好。现在,如果您将 JSON 对象放入数组中,您应该会看到它应该正确呈现。当你在 setRecipes 中设置你的状态时,你没有引用你的状态,所以它不知道要重新渲染什么。因此,即使您的状态不同,它也不会被重新渲染,因此您会遇到该错误。要解决此问题,您的代码应为:

setRecipes([...allRecipes]);

该代码将首先将已经处于状态的所有内容带回,在这种情况下什么都不是。

【讨论】:

    【解决方案2】:

    你可以像这样更改useState

    const [recipes, setRecipes] = useState({});
    

    作为API返回的数组,像这样设置值,然后你会得到recipes对象,它由ingredients数组组成

     if (allRecipes?.length) setRecipes(allRecipes[0]);
    

    像这样更改JSX

    在您的 json 数据中没有第二个 ingredients

    ingredients 只有这个数据的数组

     {
       "uuid":"62798278-2fbc-4c31-98de-b7959c191688",
       "amount":1,
       "measurement":"package (19 oz)",
       "name":"queso brats"
      }
    

    要在 JSX 内部更改的代码

         <div>
            {recipes?.title}
            <ul>
              {recipes?.ingredients?.map((sub) => (
                <li>{sub?.name}</li>
              ))}
            </ul>
          </div>
    

    如果可能的话,为所有对象提供可选链接以避免错误,像这样

    {recipes?.servings}
    

    如果需要,您可以使用可选链接更改图像JSX

     <h5>Images</h5>
     <ul><li>{recipes?.images?.full}</li></ul>
     <ul><li>{recipes?.images?.medium}</li></ul>
     <ul><li>{recipes?.images?.small}</li></ul>
    

    【讨论】:

      猜你喜欢
      • 2022-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-30
      • 2015-12-21
      • 1970-01-01
      相关资源
      最近更新 更多