0
votes

I am struggling to find a way to pass my key to the root div of my return statement

  const [recipes, setRecipes] = useState([]);
  const [search, setSearch] = useState("");
  const [query, setQuery] = useState("chicken");

  useEffect(() => {
      getRecipes();
    }, [query]);

  const getRecipes = async () => {
      const response = await fetch(`https://api.edamam.com/search?q=${query}&app_id=${App_ID}&app_key=${App_Key}`);
      const data = await response.json();
      setRecipes(data.hits);
      console.log(data.hits);
  }

  const updateSearch = e => {
    setSearch(e.target.value);
    console.log(search);
  };

  const getSearch = e => {
    e.preventDefault();
    setQuery(search);
    setSearch("")
  };


  return(
      <div className="App">
          <form onSubmit={getSearch} className="search-form">
           <input 
           className="search-bar" 
           type="text" value={search} 
           onChange={updateSearch}
           placeholder="Find a recipe" />
             <button className="search-button" type="submit">
             Search
             </button>
          </form>
          <div className="recipes">
          {recipes.map(recipe => (
            <Recipe
            title={recipe.recipe.label} 
            calories={Math.round(recipe.recipe.calories)}
            image={recipe.recipe.image}
            ingredients={recipe.recipe.ingredients}/>
            ))}
          </div>
      </div>
    );

When I only pass the key to the Recipe component, I get the error "Each child in a list should have a unique "key" prop."

I assume this means that I need to pass the key to the div with className "App". How do I do that without passing the map function around the entire return statment?

1
You don't have to pass key to your enclosing div. You just need to pass key for repeated nodes, like Recipe. Just make sure each item gets a unique key. - Agus Zubiaga
You mean just within the <Recipe /> component? Because when I do that, I still get the error - c120
I believe you might be adding the key in the wrong place. Check out my answer with code examples. - Agus Zubiaga

1 Answers

1
votes

You do not need a key on your enclosing div. You only need keys on the nodes you're repeating, and you should make sure that this key is unique amongst all items.

It's common for data entries to have an ID field. If you have one, and it's unique, you should probably use that for the key:

          {recipes.map(recipe => (
            <Recipe
              key={recipie.recipe.id}
              title={recipe.recipe.label} 
              calories={Math.round(recipe.recipe.calories)}
              image={recipe.recipe.image}
              ingredients={recipe.recipe.ingredients}
            />
          ))}

If you don't, you could rely on the index:

          {recipes.map((recipe, index) => (
            <Recipe
              key={index}
              title={recipe.recipe.label} 
              calories={Math.round(recipe.recipe.calories)}
              image={recipe.recipe.image}
              ingredients={recipe.recipe.ingredients}
            />
          ))}

Use this option as a last resort. If the order of your items changes, React might not be able to reuse the items and this might affect performance.

Note: key is a special property that React uses to know which elements have changed and how it needs to update them. React manages the key prop, and your component implementation does not have to do anything about it. You just need to pass it when you're creating many of the same.

You can read more about keys here: https://reactjs.org/docs/lists-and-keys.html