并非 <div> 内的所有元素都会被渲染。 React.js

问题描述 投票:0回答:1

带有标有“查看食谱”按钮的食谱卡

这是一个菜谱应用程序,其中显示的所有数据均从 Spoonaulous (API) 获取,当用户单击菜谱卡上的按钮(查看菜谱)时,将显示有关菜谱的详细信息,如下所示。

仅渲染带有文本:Ingredients 的 h2 元素,但其他 div 未渲染

显示除成分外的所有详细信息,并且不显示错误消息。

IngredientsList父组件代码(所有组件的父组件为App.jsx):

import { useEffect, useState } from "react";
import styles from "./FoodDetails.module.css";
import IngredientsList from "./IngredientsList";

export default function FoodDetails({ foodId }) {
  const [recipe, setRecipe] = useState({});
  const [isLoading, setIsLoading] = useState(true);
  const URL = `https://api.spoonacular.com/recipes/${foodId}/information`;
  const API_KEY = "";
  let UniqueKey = 0;

  useEffect(() => {
    async function fetchRecipe() {
      const res = await fetch(`${URL}?apiKey=${API_KEY}`);
      const data = await res.json();
      console.log(data);
      setRecipe(data);
      setIsLoading(false);
    }

    if (foodId !== "") {
      fetchRecipe();
    }
  }, [foodId]);

  if (foodId !== "") {
    return (
      <div>
        <div className={styles.recipeContainer}>
          <h1 className={styles.recipeName}>{recipe.title}</h1>
          <img className={styles.recipeImage} src={recipe.image} alt="" />
          <div className={styles.recipeDetails}>
            <span>
              ⏳<strong>{recipe.readyInMinutes} Minutes</strong>
            </span>
            <span>
              👨‍👩‍👧‍👦 <strong>Serves {recipe.servings}</strong>
            </span>
            <span>
              <strong>
                {recipe.vegetarian ? "🥕 vegetarian" : "🥩 non-vegetarian"}
              </strong>
            </span>
            <span>
              <strong>{recipe.vegan ? "🐮 vegan" : ""}</strong>
            </span>
            <span>
              <strong>
                ${Math.floor(recipe.pricePerServing / 100)} Per Serving
              </strong>
            </span>
          </div>

          <div>
            <h2>Ingredients</h2>
            <IngredientsList recipe={recipe} isLoading={isLoading} />
          </div>
          
          <div className={styles.recipeInstructions}>
            <h2>Instructions</h2>
            <ol>
              {isLoading ? (
                <p>Loading....</p>
              ) : (
                recipe.analyzedInstructions[0].steps.map((step) => (
                  <li key={(UniqueKey = UniqueKey + 1)}>{step.step}</li>
                ))
              )}
            </ol>
          </div>
        </div>
      </div>
    );
  }
}

导致问题的部分代码:

<div>
     <h2>Ingredients</h2>
     <IngredientsList recipe={recipe} isLoading={isLoading} />
</div>

<IngredientsList />
是子组件,包含成分组件,它接受
recipe
isLoading
作为道具。

里面的代码

<IngredientsList />
:

import Ingredient from "./Ingredient";

export default function IngredientsList({ recipe, isLoading }) {
  return (
    <div>
      {isLoading ? (
        <p>Loading....</p>
      ) : (
        recipe.extendedIngredients.map((item) => {
          <Ingredient item={item} />;
        })
      )}
    </div>
  );
}

extendedIngredients 是包含所有数据的对象的数组属性,recipe 是对象,因此使用映射我循环遍历它,并将每个“详细信息”对象作为项目并将其作为道具传递给

<Ingredient />
组件。

里面的代码

<Ingredient />
:

export default function Ingredient({ item }) {
  return (
    <div>
      <img
        src={`https://img.spoonacular.com/ingredients_100x100/` + item.image}
        alt=""
      />

      <div>
        <h1>{item.name}</h1>
        <p>
          {item.amount} {item.unit}
        </p>
      </div>
    </div>
  );
}

成分中的所有内容均不显示。

我认为扩展成分数组属性无法访问,因为一开始就出现错误消息,但是当在 item 属性上使用

console.log()
时,它显示的对象没有错误。但是,当编写删除 Ingredient.jsx 中 div 的所有内容并创建 h1 元素时,它会被渲染。

javascript reactjs arrays components visual-web-developer
1个回答
0
投票

在您的代码中,map函数不返回成分组件。它应该返回每个项目的 JSX 元素。另外,每个组件应该是唯一的,因此必须添加密钥,如果您没有唯一的密钥,您可以随时用映射函数中传递的索引替换它。

import Ingredient from "./Ingredient";

export default function IngredientsList({ recipe, isLoading }) {
  return (
    <div>
      {isLoading ? (
        <p>Loading....</p>
      ) : (
        recipe.extendedIngredients.map((item) => (
          <Ingredient key={item.id} item={item} />
        ))
      )}
    </div>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.