嘿,我正在学习 reactjs,就像我学到的一样,我正在尝试将笔记应用程序作为下面给出的代码
我的 App.js 文件
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;
我的 Sidebar.js 文件
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>
</>
)
}
我的 Editor.js 文件
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>
</>
)
}
每当我单击添加按钮或任何侧边栏按钮时,它都会显示错误
未捕获的类型错误:无法读取未定义的属性(读取“标题”)
请帮我解决这个问题
您期望getNotes
(可能应该命名为getActiveNote
恕我直言)每次都重新运行notes
或currentNoteID
更改。
为此,您必须将其声明为回调 ( useCallback
) 并声明其依赖项。您还希望将结果置于状态 ( 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} />
...此时,您不再需要currentNoteID
in ,<Editor />
因为您可以从props.note.id
.
看到它在这里工作:https ://codesandbox.io/s/crazy-glade-qb94qe?file=/src/App.js:1389-1448
注意:同样的事情需要发生在<Editor>
,note
更改时:
useEffect(() => setEdit(note), [note]);
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句