这是一个菜谱应用程序,其中显示的所有数据均从 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 元素时,它会被渲染。
在您的代码中,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>
);
}