React: Key prop is not being recognized

I have a React app that renders Recipes from an API. I am supposed to pass in a key that sets each recipe to a unique id. And so I did thisn

return(
    
      <div className="container">
        <input className="input" onChange={updateRecipes} value={search} type="text"></input>
        <button className="search-button"type="submit" onClick={getSearch}>Search</button>
          <div>
          {recipes.map(recipe => (
          <Recipes 
            key={recipe.recipe.label}
            title={recipe.recipe.label} 
            calories={recipe.recipe.calories} 
            image={recipe.recipe.image}  
            ingredients={recipe.recipe.ingredients} />
        ))}
        </div>
      </div>
      
    );

I set the key={recipe.recipe.label} just like all the other props. But I get an error message saying Warning: Each child in a list should have a unique "key" prop. How do I fix this?

          {recipes.map((recipe, key) => (
          <Recipes 
            key={key}
            title={recipe.recipe.label} 
            calories={recipe.recipe.calories} 
            image={recipe.recipe.image}  
            ingredients={recipe.recipe.ingredients} />
        ))}

Would UUID be a good library for this then? Depending if it is reading the ID’s from the backend?

That is what I was trying to do. I don’t think I was implementing it correctly however. Here is the rest of my code if that helps

import React, {useEffect, useState} from'react';
import Recipes from './Recipes';
// import uuidv4 from 'uuid/v4'
import './App.css';



function App() {
const API_ID = 'c38daf94';
const API_KEY = '850d468a3e994692691631c7c259406c';


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=${API_ID}&app_key=${API_KEY}`
    )
    const data = await response.json();
    setRecipes(data.hits)
    console.log(data.hits)
  }

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

  const getSearch = e => {
    e.preventDefault();
    setQuery(search)
  }
    return(
    
      <div className="container">
        <input className="input" onChange={updateRecipes} value={search} type="text"></input>
        <button className="search-button"type="submit" onClick={getSearch}>Search</button>
          <div>
          {recipes.map(recipe => (
          <Recipes 
            key={recipe.}
            title={recipe.recipe.label} 
            calories={recipe.recipe.calories} 
            image={recipe.recipe.image}  
            ingredients={recipe.recipe.ingredients} />
        ))}
        </div>
      </div>
      
    );
  }
  
  export default App;

@fkhan698, so the response from API doesn’t provide id of the recipe?

1 Like

I guess not. I was following a tutorial that used this same API and they just put key={recipe.recipe.label}

Yes, unless you have a good id value from the backend to use. Simplest way is just install uuid and probably use v4.

> npm install --save uuid
import uuid from "uuid/v4";

....
  <MyComponent key={uuid} .........
....

I guess there will be some overhead from computing the uuids, but IME I’ve never been in a situation where it’s been an issue, and it’s always fixed any key problems I’ve had immediately

https://developer.edamam.com/edamam-docs-recipe-api

I did this, but am still getting an error

What is the error that’s coming up?

This is the error I get

I went ahead and put in key={recipe.recipe.uri} but still no luck. I keep getting the same error message

For you to be getting duplicate keys when they’re uuids, and I’m reading that error correctly, that means you’re generating a key then using that same key for multiple items, the chances of a collision are astronomically small otherwise. Need to see more code I think

Edit: ah, I see, if you copied my code verbatim, uuid is function, it need to be uuid(). If you just used uuid, you’re trying to set every key to the definition of a specific function. Note I just use uuids out of habit because I’m lazy and I can’t be bothered to do any thinking when I want a unique id, there are other very simple ways to create something semi unique without importing a lib

Yes I have it on https://github.com/fkhan698/recipes-react-app

The warning is coming from the ingredients.map inside Recipes.js. You need to give the <li> a key.