2

Hey I am learning reactjs as much as i have learned I am trying to make note app my code given below

my App.js file

 import React , {useEffect, useState} from "react"
import { nanoid } from "nanoid"
import Editor from './Note/Editor'
import Sidebar from "./Note/Sidebar"


function App() {

  const [notes , setNotes] = useState(JSON.parse(localStorage.getItem("notes"))||[])
  const [currentNoteID , setCurrentNoteID] = useState(false)

  useEffect(()=>{
    localStorage.setItem("notes" , JSON.stringify(notes))
  },[notes])

  function createNewNotes(){
    const newNotes = {
      id: nanoid(),
      title:"untitled",
      body: "sdasda",
      lastModified: Date.now()
    }
    setNotes(prevNote => [newNotes , ...prevNote])
    setCurrentNoteID(newNotes.id)
  }

  function deleteNote(noteID){
    setNotes(prevNote => prevNote.filter(note=> note.id !== noteID ))
  }

  function getNotes(){

    return notes.find((note)=> note.id === currentNoteID)
  }
  return (
    <div className="note">
      <Sidebar
      notes={notes}
      createNewNotes={createNewNotes}
      currentNoteID={currentNoteID}
      setCurrentNoteID={setCurrentNoteID}
      deleteNote={deleteNote}
      />

      
            <Editor
              notes={getNotes()}
              currentNoteID={currentNoteID}/>
      
     

    </div>
   
  );
}

export default App;

my Sidebar.js file

 import React from 'react'
import './style.css'

export default function Sidebar(props){

    return(
        <>

            <div className='sidebar' >
                <div className='sidebar-header'>

                    <h3>Notes</h3>
                    <button className='add' onClick={props.createNewNotes} >Add</button>
                </div>
                   
           { props.notes.map((note)=>{
               return(

                   
                   <div key={note.id} 
                   className={`${note.id===props.currentNoteID ? "active" : ""}`} 
                   onClick={()=>props.setCurrentNoteID(note.id)}
                   >
                        <div>
                    <div className="sidebar-tab">

                        <div className='sidebar-title'>
                            <p className='title'>Untitled</p>
                        <button className='delete' onClick={()=>props.deleteNote(note.id)}>Delete</button>

                        </div>
                            <p className='note-preview'>summary of text</p>
                            
                    </div>
                    </div>

            </div>
            )
            })}
                </div>
        </>
    )
}

my Editor.js file

 import React , {useState} from "react";
import './style.css'

export default function Editor(props){

    const [edit , setEdit] = useState(props.notes) 

  function handleChange(event){
      const {name , value} = event.target
       setEdit(prevNote=> {
           return {
                ...prevNote,
                [name] : value

            }
        })

    }
    
if(!props.currentNoteID)
    return  <div className="no-note">no note active</div>
    return(
        <>
            <div className="main">
                <input type="text" className="main-input" name="title" placeholder="Enter title here" value={edit.title} onChange={handleChange}  autoFocus/>
                <textarea className="main-textarea" name="body"  placeholder="Type your notes" value={edit.body} onChange={handleChange} />
              


                <div className="preview">
                    <h1 className="preview-title">{edit.title}</h1>
                    <div className="main-preview">{edit.body}</div>
                </div>
                 

            </div>
        </>
    )
    
}

whenever i click add button or any sidebar button it shows me error

Uncaught TypeError: Cannot read properties of undefined (reading 'title')

please help me out how to fix this issue

Kush
  • 41
  • 1
  • 5
  • Please read [ask]. Namely, you have to give your question a relevant title for the error you're seeing (e.g: `Cannot read properties of undefined (reading *)`. Additionally, you should not add your entire app into the question, only the minimal necessary code to repro the issue. – a.h.g. Apr 10 '22 at 14:32
  • hey a.h.g sorry for that actually i started recently so, I don't know how to ask a question in a manner way From now i will take care of it – Kush Apr 10 '22 at 16:27
  • Please help me out how to fix this issue – Kush Apr 11 '22 at 06:36
  • 1
    If you could find a smaller example that shows the error that might help people answer it. Try removing parts of the file one at a time until either (a) the problem goes away (then you can tell us what line of code in what file fixed it), or (b) you get to a very minimal example (small number of files and small number of lines in each file) that still demonstrates the problem. This will make it easier for others to help you (and it is also a good debugging skill in general for helping yourself understand a problem). – Acorn Apr 13 '22 at 15:31

1 Answers1

1

You're expecting getNotes (which should probably be named getActiveNote, IMHO) to re-run every time notes or currentNoteID change.

To achieve this, you have to declare it as a callback (useCallback) and to declare its dependencies. Also you want to place the result in state (e.g: activeNote):

const getActiveNote = useCallback(
  () => notes.find((note) => note.id === currentNoteID),
  [notes, currentNoteID]
);
const [activeNote, setActiveNote] = useState(getActiveNote());
useEffect(() => {
  setActiveNote(getActiveNote());
}, [getActiveNote]);


   // ...
   <Editor note={activeNote} />

... at which point, you no longer need the currentNoteID in the <Editor /> as you can get it from props.note.id.

See it working here: https://codesandbox.io/s/crazy-glade-qb94qe?file=/src/App.js:1389-1448

Note: the same thing needs to happen in <Editor>, when note changes:

useEffect(() => setEdit(note), [note]);
a.h.g.
  • 1,429
  • 3
  • 12
  • Thank you so much @a.h.g. , you replied, my problem was solved, but you have put in a little advance concept, I try to understand. – Kush Apr 11 '22 at 12:19