I have a simple component tree:
RecipeFeed which renders Recipe
In my RecipeFeed component I map an an array of recipe objects to render a Recipe component for each recipe object in the array
const renderRecipes = () => {
if (recipes) {
return (
<div>
{recipes.map(recipe =>
<Recipe
key={recipe.id}
recipe={recipe}
ingredients={recipe.ingredients}/>
)}
</div>
)
} else {
return (
<div>
....loading
</div>
)
}
}
My Recipe component is similar:
const renderIngredients = () => {
if (props.ingredients) {
props.ingredients.map(ingredient => {
console.log(ingredient.name)
<div>{ingredient.name}</div>
})
}
}
return (
<div>
<div>{props.recipe.name}</div>
{renderIngredients()}
</div>
)
}
My recipe.name
is OK, and renders to the DOM. However, although my ingredients are defined in the console.log in Recipe.jsx, Nothing is rendered to the screen.
I believe it must have something to do with the shape of the data and the way I am trying to access the value, but I am confused why it appears to be okay when inspecting the console log - right value type of string, no errors, etc.
The json data looks like this
"data": [
{
"id": 2,
"name": "pizza",
"ingredients": [
{
"id": 5,
"name": "dough",
"food_group": "grain",
"created_at": "2022-03-08T04:39:41.334Z",
"updated_at": "2022-03-08T04:39:41.334Z"
},
{
"id": 6,
"name": "sauce",
"food_group": "vegetable",
"created_at": "2022-03-08T04:40:11.684Z",
"updated_at": "2022-03-08T04:40:11.684Z"
},
{
"id": 7,
"name": "cheese",
"food_group": "dairy",
"created_at": "2022-03-08T04:40:33.032Z",
"updated_at": "2022-03-08T04:40:33.032Z"
}
],
"recipe_ingredients": [
{
"id": 3,
"recipe_id": 2,
"ingredient_id": 5,
"quantity": null,
"measurement_unit": null,
"created_at": "2022-03-08T04:41:06.482Z",
"updated_at": "2022-03-08T04:41:06.482Z"
},
{
"id": 4,
"recipe_id": 2,
"ingredient_id": 6,
"quantity": null,
"measurement_unit": null,
"created_at": "2022-03-08T04:41:06.484Z",
"updated_at": "2022-03-08T04:41:06.484Z"
},
{
"id": 5,
"recipe_id": 2,
"ingredient_id": 7,
"quantity": null,
"measurement_unit": null,
"created_at": "2022-03-08T04:41:06.485Z",
"updated_at": "2022-03-08T04:41:06.485Z"
}
]
}
CodePudding user response:
You've got numerous mistakes here.
First: the second return
statement is not inside a function. It's not part of the renderIngredients
function -- which it can't be anyway, since then it would call itself. (Yes, recursion is legit in javascript, but this case would be perfectly circular and thus break.)
(On second glance, this is maybe because you forgot to include the beginning of the Recipe component, but we're not mind readers here.)
Second: your renderIngredients
function won't accomplish anything, because: (1) it does not return anything, and (2) the map
inside it also doesn't return anything. This is the direct answer to your question, "Why is my component not rendering a prop value?": it's because you haven't chosen to return anything, either with the return
keyword, or by using the short arrow form: () => returnValue
.
Third: the signature of your Recipe component is bad:
<Recipe
key={recipe.id}
recipe={recipe}
ingredients={recipe.ingredients}
/>
Why are you passing both the recipe
and the ingredients
separately? The component can access the ingredients through the recipe. You've set it up so that the same data has to be fed into it twice.
Fourth: the names of component functions must start with a capital letter so that the React framework recognizes them as custom components instead of native HTML components. And don't name your component "renderRecipes", name it "RecipeList".
CodePudding user response:
//you are not returning ingredients so here is the
//updated renderIngredients methods
const renderIngredients = () => {
if (props.ingredients) {
return props.ingredients.map(ingredient => {
console.log(ingredient.name)
<div>{ingredient.name}</div>
})
}
return
}