Home > Software engineering >  Why is my component not rendering a prop value?
Why is my component not rendering a prop value?

Time:03-11

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"
        }
      ]
    }

screenshot

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
  }

  • Related