Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding an element to the todo list not working, and getting "Each child in a list should have a unique key prop" in React

So I'm trying to make a to-do list, and it's not working when I try to add an item to the list with addItemToList. I am getting this error:

Each child in a list should have a unique “key” prop

App code:

function App() {
  const [currentItem, setCurrentItem] = useState("");
  const [itemlist, updateItemList] = useState([]);

  const onChangeHandler = (e) => {
    setCurrentItem(e.target.value);
  };

  const addItemToList = () => {
    updateItemList([...itemlist, { item: currentItem, key: Date.now() }]);
    setCurrentItem("");
  };

  return (
    <div className="App">
      <header>
        <form id="to-do-form">
          <input
            type="text"
            placeholder="Enter Text"
            value={currentItem}
            onChange={onChangeHandler}
          />
          <button onClick={addItemToList} type="submit">
            Add
          </button>
        </form>
        <List itemlist={itemlist} />{" "}
      </header>
    </div>
  );
}

List code:

function List(props) {
  return (
    <div>
      {props.itemlist.map((itemObj) => {
        return <p>{itemObj.item}</p>;
      })}
    </div>
  );
}
like image 825
imtryingmybestprogrammer Avatar asked Oct 25 '25 13:10

imtryingmybestprogrammer


2 Answers

Since each item object in your case already has a key prop equal to Date.now(), you could use it, this way:

function List(props) {
  return (
    <div>
      {props.itemlist.map((itemObj) => {
        return <p key={itemObj.key}>{itemObj.item}</p>;
      })}
    </div>
  );
}

But if you haven't a key prop on your items, you could use the index from map, like so:

function List(props) {
  return (
    <div>
      {props.itemlist.map((itemObj, index) => {
        return <p key={index}>{itemObj.item}</p>;
      })}
    </div>
  );
}

Also, you need to prevent the browser from refreshing the page after submitting the form in addItemToList with e.preventDefault() to see the added item:

 const addItemToList = (e) => {
    e.preventDefault();
    updateItemList([...itemlist, { item: currentItem, key: Date.now() }]);
    setCurrentItem("");
  };
like image 138
yousoumar Avatar answered Oct 27 '25 03:10

yousoumar


You probably have an itemlist.map which transforms this array in jsx element to render.

This element needs an unique key, its a prop that helps react render your list correctly.

So, you can pass this prop after map this list {itemlist.map(item => <element key={item.UNIQUE_KEY} />)}

If you dont have an unique key, you can pass the index of your map, but its not recommended because if you modify this list, react will recalculate all those index again

{itemlist.map((item, index) => <element key={index} />)}

like image 27
Gabriel Alcântara Avatar answered Oct 27 '25 03:10

Gabriel Alcântara