2

I am trying to make a React Notes app with the API. Everything works fine, but when I add a new note, I am facing this warning: Each child in a list should have a unique "key" prop. Check the render method of `Notes`

you can check the notes component here,

{notes.length === 0 ? (
          <p>No notes to display</p>
        ) : (
          notes.map(({ id, title, body, created }) => (
            <li className="note" key={id}>
              <div className="details">
                <p>{title}</p>
                <span>{body}</span>
              </div>
              <div className="bottom-content">
                <span>{formatDate(created)}</span>

                <div
                  className={`settings ${
                    showMenu && selectedNoteId === id ? "show" : ""
                  }`}
                >
                  <AiOutlineEllipsis
                    className="icon"
                    onClick={() => toggleMenu(id)}
                  />

                  <ul className={"menu"}>
                    <li
                      onClick={() => handleEdit({ id, title, body, created })}
                    >
                      <BiPencil />
                      Edit
                    </li>

                    <li onClick={() => toggleDeletePopup(id)}>
                      <BiTrash />
                      Delete
                    </li>
                  </ul>
                  {selectedDeleteNoteId === id && (
                    <DeletePopup
                      onCancel={handleDeleteCanceled}
                      deleteConfirmed={() => handleDeleteConfirmed(id)}
                    />
                  )}
                  {selectedEditNote && selectedEditNote.id === id && (
                    <EditNotePopup
                      note={selectedEditNote}
                      onSubmit={handleNoteUpdate}
                      onCancel={() => setSelectedEditNote(null)}
                    />
                  )}
                </div>
              </div>
            </li>
          ))
        )}

and here is the add-new note component

return (
    <div className="newnote-popup">
      <div className="card">
        <header>
          <h3>Add a new note</h3>
          <FaTimes className={"x"} onClick={handleCancel} />
        </header>
        <form onSubmit={handleSubmit}>
          <div className="note-title">
            <label>Title</label>
            <input
              type="text"
              name="title"
              value={note.title}
              onChange={handleChange}
              maxLength={50}
              autoComplete="none"
            />
            <small className="character-count">{titleCount}/50 </small>
          </div>
          <div className="note-body">
            <label>Description</label>
            <textarea
              name="body"
              value={note.body}
              onChange={handleChange}
              placeholder="Your Note"
              maxLength={400}
            />
            <small className="character-count">{characterCount}/400 </small>
          </div>
          <div className="buttons">
            <button type="submit">Add Note</button>
          </div>
        </form>
      </div>
    </div>
  );

I searched for this problem, and all the solutions were to add a unique key, but I already added the key with an ID in my code. So what is the problem, guys?

iChelsi
  • 459
  • 1
  • 12
Tevfik
  • 37
  • 5
  • Does this answer your question? [Understanding unique keys for array children in React.js](https://stackoverflow.com/questions/28329382/understanding-unique-keys-for-array-children-in-react-js) – Harrison Aug 11 '23 at 11:09
  • 1
    Either `id` is not unique or this is no the list that is causing the warning – Konrad Aug 11 '23 at 11:09
  • Does this answer your question? [Can I add a key prop to a React fragment?](https://stackoverflow.com/questions/59390955/can-i-add-a-key-prop-to-a-react-fragment) – Audun Hilden Aug 11 '23 at 11:36

4 Answers4

1

Try this .Rest of the code will remain same

notes.map(({ id, title, body, created },index) => (
            <li className="note" key={index}>
1

Maybe you're not getting the unique id. Just do this

notes.map(({ id, title, body, created }, index) => (
    <li className="note" key={index}>
    .....
    </li>
)
iChelsi
  • 459
  • 1
  • 12
0

In your code snippet, you are indeed assigning a unique key to each "<li>" element using the id property from the notes array. This should be correct, and there doesn't seem to be an issue with the key prop itself.

I think, The issue might be elsewhere in your code, possibly in how you're adding a new note. If you're adding a new note without assigning a unique id to it before rendering, that could cause the error. Make sure that when you add a new note, you provide a unique id to it before rendering it in the list. Add this code:

// Inside your component's state
const [note, setNote] = useState({
  id: generateUniqueId(), // Use a function to generate a unique id
  title: "",
  body: "",
  created: new Date().toISOString(), // You can adjust this as needed
});

// Function to handle adding a new note
const handleSubmit = (e) => {
  e.preventDefault();
  
  // Ensure note has a unique id
  const newNote = { ...note, id: generateUniqueId() };
  
  // Add the new note to your notes array
  const updatedNotes = [...notes, newNote];
  
  // Update the state with the new notes
  setNotes(updatedNotes);
  
  // Clear the form or reset the note state for a new note
  setNote({
    id: generateUniqueId(),
    title: "",
    body: "",
    created: new Date().toISOString(),
  });
};

// Function to generate a unique id
const generateUniqueId = () => {
  return Math.random().toString(36).substr(2, 9);
};
-1

thank you guys , i solved by adding index

notes.map(({ id, title, body, created }, index) => (
        <li className="note" key={`${id}-${index}`}>
Tevfik
  • 37
  • 5