0

I am trying to map through a component (Note) and another component (newNote). like in the following App.jsx

import React, { useState } from "react";
import Header from "./Header";
import Footer from "./Footer";
import Note from "./Note";
import CreateArea from "./CreateArea";

function App() {
  const [notes, setNotes] = useState([]);

  function addNote(newNote) {
    setNotes(prevNotes => {
      return [...prevNotes, newNote];
    });
  }

  function deleteNote(id) {
    setNotes(prevNotes => {
      return prevNotes.filter((noteItem, index) => {
        return index !== id;
      });
    });
  }

  return (
    <div>
      <Header />
      <CreateArea onAdd={addNote} />
      {notes.map((noteItem, index) => {
        return (
          <Note
            key={index}
            id={index}
            title={noteItem.title}
            content={noteItem.content}
            onDelete={deleteNote}
          />
        );
      })}
 {notes.map((noteItem, index) => {
        return (
          <newNote
            key={index}
            id={index}
            title={noteItem.title}
            content={noteItem.content}
            onDelete={deleteNote}
          />
        );
      })}
      <Footer />
    </div>
  );
}

export default App;

What I need to do is map the newNote component inside the Note component like the following.

import React, { useState } from "react";
import Header from "./Header";
import Footer from "./Footer";
import Note from "./Note";
import CreateArea from "./CreateArea";

function App() {
  const [notes, setNotes] = useState([]);

  function addNote(newNote) {
    setNotes(prevNotes => {
      return [...prevNotes, newNote];
    });
  }

  function deleteNote(id) {
    setNotes(prevNotes => {
      return prevNotes.filter((noteItem, index) => {
        return index !== id;
      });
    });
  }

  return (
    <div>
      <Header />
      <CreateArea onAdd={addNote} />
      {notes.map((noteItem, index) => {
        return (
          <Note
            key={index}
            id={index}
            title={noteItem.title}
            content={noteItem.content}
            onDelete={deleteNote}
          />
          {notes.map((noteItem, index) => {
            return (
              <newNote
                key={index}
                id={index}
                title={noteItem.title}
                content={noteItem.content}
                onDelete={deleteNote}
              />
            );
          })}
        );
      })}
     
      <Footer />
    </div>
  );
}

export default App;

But it does not work. This link explains what I am trying to achieve but I need to achieve that with components. https://bobbyhadz.com/blog/react-map-nested-array

4
  • Please share the data structure you've got in notes. You are simply looping over the same notes variable and not actually doing a nested operation. Commented Aug 5, 2022 at 15:12
  • I need them to use the same array notes. that is on purpose. but what I am trying to ask is why i get an error when I add the code this way? it does not compile at all when I add the newNotes component inside the main Note and map through them both, even though it works in the link I provided. (syntax error) Commented Aug 5, 2022 at 15:20
  • 1
    Okay, can you plz share the syntax error you get? It is probably because you need to wrap the content of the return statement with return (<React.Fragment> ...your map loops... </React.Fragment>) or short return (<> ... </>). Commented Aug 5, 2022 at 15:26
  • 1
    Oh yea that actually fixed my error. thank you so much! It was missing <> .. </>. Commented Aug 5, 2022 at 16:06

2 Answers 2

1

It's like Irfanullah suggested in the comments, you need to use a fragment to wrap your nested components. Also you could avoid using return:

{notes.map((noteItem, index) => 
        (
        <React.Fragment key={noteItem.id}> // preferred to avoid errors
          <Note
            id={index}
            title={noteItem.title}
            content={noteItem.content}
            onDelete={deleteNote}
          />
          {notes.map((noteItem, index) => (
              <newNote
                key={noteItem.id}
                id={index}
                title={noteItem.title}
                content={noteItem.content}
                onDelete={deleteNote}
              />
            )
          )}
        )
      </React.Fragment>
      )}

Edited as per Irfanullah's comment

Do not use index for key as it would create problems in update, delete, operations.

Sign up to request clarification or add additional context in comments.

1 Comment

One thing to add: instead of polluting the DOM with unnecessary div elements, it is best to use <React.Fragement key={index}> instead. Also if the notes order is expected to change, we might get unexpected behavior by using array index as keys, and should use a more unique and stable key e.g. note ID or something.
0

when you're calling the notes.map() the first time you're getting the noteItem right?, now when you nest inside you can use the map function on the noteItem component and not the notes itself .......... Even in the source you provided he mapped the array and then during second time mapped over the object inside

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.