Step 10: Delete Notes

Replace the content of App.jsx with the following:

import { useEffect, useState } from "react";
import { faker } from "@faker-js/faker";
import Notes from "./components/Notes";
import { Container } from "@mantine/core";
import Search from "./components/Search";

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

  useEffect(() => {
    const fakeNotes = [];
    for (let index = 0; index < 10; index++) {
      fakeNotes.push({
        id: faker.datatype.uuid(),
        title: faker.lorem.sentence(),
        text: faker.lorem.paragraph(),
      });
    }
    setNotes(fakeNotes);
  }, []);

  const remove = (id) => {
    setNotes((notes) => notes.filter((note) => note.id !== id));
  };

  return (
    <Container>
      <Search query={query} setQuery={setQuery} />
      <Notes notes={notes} query={query} remove={remove} />
    </Container>
  );
}

export default App;

Notice:

  • I added an id attribute to each note.
  • I added a remove method that provided an id, it will update the state by removing the corresponding note.
  • The remove function is passed to the Notes component.

Next, update the Notes.jsx file to pass the remove function to the Note component as follows:

  import Note from "./Note";
  import PropTypes from "prop-types";
  import { Accordion } from "@mantine/core";
	
  function Notes(props) {
-   const { notes, query } = props;
+   const { notes, query, remove } = props;
	
    return (
      <Accordion chevronPosition="left">
        {notes
          .filter(
            (note) =>
              note.title.toLowerCase().includes(query.trim().toLowerCase()) ||
              note.text.toLowerCase().includes(query.trim().toLowerCase())
          )
          .map((note, index) => (
-          <Note key={index} note={note} />
+          <Note key={index} note={note} remove={remove} />
          ))}
      </Accordion>
    );
  }
	
  export default Notes;
	
  Notes.propTypes = {
+   remove: PropTypes.func.isRequired,
    query: PropTypes.string,
    notes: PropTypes.arrayOf(
      PropTypes.shape({
        title: PropTypes.string.isRequired,
        text: PropTypes.string.isRequired,
      })
    ),
  };

Moreover, update the Note.jsx file to pass the remove function to the NoteControl component as follows:

  import PropTypes from "prop-types";
  import { Accordion } from "@mantine/core";
  import NoteControl from "./NoteControl";
	
  function Note(props) {
-   const { note } = props;
+   const { note, remove } = props;
	
    return (
      <Accordion.Item value={note.title}>
-       <NoteControl note={note} />
+       <NoteControl note={note} remove={remove} />
        <Accordion.Panel>{note.text}</Accordion.Panel>
      </Accordion.Item>
    );
  }
	
  export default Note;
	
  Note.propTypes = {
+   remove: PropTypes.func.isRequired,
    note: PropTypes.shape({
      title: PropTypes.string.isRequired,
      text: PropTypes.string.isRequired,
    }),
  };

Finally, update the NoteControl.jsx files to execute the remove function as follows:

  import PropTypes from "prop-types";
  import { Accordion, ActionIcon, Box } from "@mantine/core";
  import { IconTrashX } from "@tabler/icons";
	
  function NoteControl(props) {
-   const { note } = props;
+   const { note, remove } = props;
	
    const handleOnRemove = () => {
+     remove(note.id);
    };
	
    return (
      <Box sx={{ display: "flex", alignItems: "center" }}>
        <Accordion.Control>{note.title}</Accordion.Control>
        <ActionIcon onClick={handleOnRemove} size="lg">
          <IconTrashX size={16} />
        </ActionIcon>
      </Box>
    );
  }

  export default NoteControl;
	
  NoteControl.propTypes = {
+   remove: PropTypes.func.isRequired,
    note: PropTypes.shape({
      title: PropTypes.string.isRequired,
      text: PropTypes.string.isRequired,
    }),
  };

Observer the delete behavior: