Leonardo Hurovich
Leonardo Hurovich

Reputation: 1

How can I get my Note element to update when I change its text?

sorry for the long post, but I'm really stuck in this part of my project. I'm using React to build a notes app, and I can't get my note to update when I alter the text inside of my modal popup...the commented out parts are where I'm having trouble (I wrote what I thought of doing, but don't know how. I've been using React for less than a week). Thank you in advance!

App.js

import React, { useState } from "react";
import { nanoid } from "nanoid";
import NotesList from "./Components/NotesList";
import AddNote from "./Components/AddNote";

const App = () => {
  const [notes, setNotes] = useState([
    /*empty array of notes*/
  ]);

  const addNote = (title, text) => {
    const date = new Date();
    const newNote = {
      id: nanoid(),
      title: title,
      text: text,
      date: date.toDateString(),
    };
    const newNotes = [...notes, newNote];
    setNotes(newNotes);
  };

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

  const editNote = (text, title, id) => {
    const editDate = new Date();
    const editedNote = {
      id: nanoid(),
      title: title,
      text: text,
      date: editDate.toDateString(),
    };
    
    const editedNotes = notes.map((note) => {
      if (note.id == id) {
        return editedNote;
      }
      return note;
    });
    setNotes(editedNotes);
  };

  return (
    <div className="container">
      <AddNote handleAddNote={addNote} />
      <NotesList
        notes={notes}
        handleAddNote={addNote}
        handleDeleteNote={deleteNote}
        editNote={editNote}
        updateNote={updateNote}
      />
    </div>
  );
};

export default App;

NotesList.js

import Note from "./Note";
import React, { useState } from "react";
import MyModal from "./Modal";

const NotesList = ({ notes, handleDeleteNote, updateNote })=> {
  const [open, setOpen] = useState(false);
  const [note, setNote] = useState({});

  const handleOpen = (id) => {
    setNote(notes.filter((note) => note.id === id)[0]);
    setOpen(true);
  };

  const handleClose = () => {
    setNote({});
    setOpen(false);
  };
  const clickedTodo = useState({});
  return (
    <div className="notes-list">
      <div className="blank-note"></div>
      <div className="existing-notes">
        <MyModal
          note={note}
          clickedTodo={clickedTodo}
          handleClose={handleClose}
          open={open}
          updateNote={updateNote}
        />
        {notes.map((note) => (
          <Note
            id={note.id}
            title={note.title}
            text={note.text}
            date={note.date}
            handleOpen={handleOpen}
            handleDeleteNote={handleDeleteNote}
          />
        ))}
      </div>
    </div>
  );
};

export default NotesList;

AddNote.js

import { useState } from "react";
import React from "react";

const AddNote = ({ handleAddNote, isUpdate, note, updateNote }) => {
  const [noteTitle, setNoteTitle] = useState("");
  const [noteText, setNoteText] = useState("");
  const characterLimit = 300;

  const handleChange = (event) => {
    if (characterLimit - event.target.value.length >= 0) {
      setNoteText(event.target.value);
    }
  };

  const handleChange2 = (event) => {
    if (characterLimit - event.target.value.length >= 0) {
      setNoteTitle(event.target.value);
    }
  };
 
  const handleSaveClick = () => {
    // if (!isUpdate) then do this
    // if (!isUpdate) {
      (noteText.trim().length > 0)
        handleAddNote(noteTitle, noteText);
        setNoteText("");
        setNoteTitle("");
    // } else updateNote(note.id)
    // else we use all of the info we have gotten
    // we call update note with note.id
  };

  return (
    <div className="note new">
      <h2>Add note</h2>
      <textarea className="new-text-title"
        placeholder={!isUpdate?"Add a title...":note.title}
        value={noteTitle}
        onChange={handleChange2}
      ></textarea>
      <textarea className="new-text-body"
        cols="8"
        rows="10"
        placeholder={!isUpdate?"Type your note here...":note.text}
        value={noteText}
        onChange={handleChange}
      ></textarea>
      <div className="note-footer">
        <small>Characters remaining: {characterLimit - noteText.length}</small>
        <button className="save" onClick={handleSaveClick}>
          <strong>Save</strong>
        </button>
      </div>
    </div>
  );
};

export default AddNote;

Note.js

import { MdDeleteForever } from "react-icons/md";

const Note = (props) => {
  const { id, title, text, date, handleOpen, handleDeleteNote } = props;
  const handleOpenModal = (id) => {
    handleOpen(id);
  };
  return (
    <div className="note">
      <div className="note-upper" onClick={() => handleOpenModal(id)}>
        <p className="title">
          <textarea className="text-title">{title}</textarea>
        </p>
        <textarea className="text-body">{text}</textarea>
      </div>
      <div className="note-footer">
        <div className="footer-left" onClick={() => handleOpenModal(id)}>
          <small>{date}</small>
        </div>
        <div className="footer-right">
          <MdDeleteForever
            onClick={() => {
              if (window.confirm("Delete this note?")) {
                handleDeleteNote(id);
              }
            }}
            className="delete-icon"
            size="1.3em"
          />
        </div>
      </div>
    </div>
  );
};

export default Note;

Modal.js

import React, { useState } from "react";
import { Modal, Box } from "@mui/material";
import Note from "./Note";

export default function MyModal(props) {
  const { open, handleClose, note, updateNote } = props;
  return (
    <div onClose={console.log("closing")}>
      <Modal open={open} onClose={handleClose}>
        <Box
          sx={{
            position: "relative",
            top: "50%",
            left: "32%",
            outline: "none",
          }}
        >
          <Note
            updateNote={updateNote}
            note={note}
            id={note.id}
            title={note.title}
            text={note.text}
            date={note.date}
          />
        </Box>
      </Modal>
    </div>
  );
}

Upvotes: 0

Views: 450

Answers (1)

deaponn
deaponn

Reputation: 858

Your Modal.js requires updateNote prop, but in App.js you don't supply it to NotesList.js, thus the parent prop of MyModal.js has no such prop:

<NotesList
     notes={notes}
     handleAddNote={addNote}
     handleDeleteNote={deleteNote}
     editNote={editNote}
/>

And later in NotesList.js:

<MyModal
      note={note}
      clickedTodo={clickedTodo}
      handleClose={handleClose}
      open={open}
      updateNote={updateNote} // this is missing because you are not
                              // passing this prop from the App component
/>

Upvotes: 0

Related Questions