React笔记应用数据库数据同步问题:增删后需重复操作或刷新
React笔记应用数据库同步异常问题
开发了一款支持添加、删除笔记的React应用,当前存在数据库数据同步异常:执行添加或删除笔记操作后,需要重复操作两次或刷新页面才能显示最新的数据库数据。以下是项目相关组件代码:
notesList.jsx(主组件)
主组件中定义了getNotes()方法并传递给其他组件用于获取最新数据
const NotesList = () => { const [notes, setNotes] = useState([]); const getNotes = async () => { const getNoteInformation = { email: localStorage.getItem("tokenEmail"), }; const response = await axios.post( "http://localhost:9000/api/note/get", getNoteInformation ); try { setNotes(response.data.data); } catch (error) {} }; const handleAddNote = async (tasktext) => { const addNoteInformation = { email: localStorage.getItem("tokenEmail"), taskText: tasktext, date: moment(new Date()).locale("fa").format("YYYY/MM/DD").toString(), }; if (addNoteInformation.email && addNoteInformation.taskText) { try { await axios.post( "http://localhost:9000/api/note/add", addNoteInformation ); } catch (error) {} } }; const handleDeleteNote = async (id) => { const deletedInformaion = { email: localStorage.getItem("tokenEmail"), noteId: id, }; if (deletedInformaion.email && deletedInformaion.noteId) { await axios.post( "http://localhost:9000/api/note/deleted", deletedInformaion ); } }; useEffect(() => { getNotes(); }, []); return ( <> <Navbar /> <div className="container"> <div className="row"> {notes .filter((notes) => notes != null) .map((notes, index) => ( <Note key={index} text={notes.text} date={notes.date} id={notes._id} deletenote={handleDeleteNote} getnote={getNotes} /> ))} <AddNote getnote={getNotes} addnote={handleAddNote} /> </div> </div> </> ); };
note.jsx
const Note = (props) => { const handleDeleteNote = () => { props.deletenote(props.id); props.getnote(); }; return ( <> <div className="col-lg-4 col-md-6 col-sm-12 p-4"> <div className="note d-flex flex-column"> <span className="note-top overflow-auto m-2 ps-2">{props.text}</span> <div className="note-bottom d-flex justify-content-between flex-row-reverse mt-auto"> <small>{props.date}</small> <MdDelete onClick={handleDeleteNote} className="delete-icon" size="1.3rem" color="#bb86fc" /> </div> </div> </div> </> ); };
addNote.jsx
const AddNote = (props) => { let addNoteText = useRef(); const handleAddNote = async () => { props.addnote(addNoteText.current.value); props.getnote(); addNoteText.current.value = ""; }; return ( <div className="col-lg-4 col-md-6 col-sm-12 p-4"> <div className="add-note-box d-flex flex-column justify-content-between"> <div className="top-box"> <textarea placeholder="یادداشت خود را وارد کنید ......" class="form-control" rows={7} ref={addNoteText} ></textarea> </div> <BsFillPlusCircleFill onClick={handleAddNote} className="plus-icon" size="1.3rem" color="#bb86fc" /> </div> </div> ); };
问题原因
核心问题是异步操作执行顺序错误:子组件调用handleAddNote/handleDeleteNote后立刻执行getNotes(),但这两个方法是异步的,后端的添加/删除操作还未完成,导致getNotes()拉取到的仍是旧数据。
另外,getNotes的错误捕获范围错误,axios请求失败时无法被捕获;handleAddNote/handleDeleteNote存在静默失败的情况,无法排查请求错误。
修复方案
方案1:确保异步操作完成后再拉取数据
修改子组件调用逻辑,等待添加/删除操作完成后再执行getNotes():
- 更新note.jsx
const handleDeleteNote = async () => { await props.deletenote(props.id); props.getnote(); };
- 更新addNote.jsx
const handleAddNote = async () => { await props.addnote(addNoteText.current.value); props.getnote(); addNoteText.current.value = ""; };
- 修正getNotes的错误捕获
const getNotes = async () => { try { const getNoteInformation = { email: localStorage.getItem("tokenEmail"), }; const response = await axios.post( "http://localhost:9000/api/note/get", getNoteInformation ); setNotes(response.data.data); } catch (error) { console.error("获取笔记失败:", error); } };
- 给handleAddNote/handleDeleteNote添加错误日志
// handleAddNote示例 const handleAddNote = async (tasktext) => { const addNoteInformation = { email: localStorage.getItem("tokenEmail"), taskText: tasktext, date: moment(new Date()).locale("fa").format("YYYY/MM/DD").toString(), }; if (addNoteInformation.email && addNoteInformation.taskText) { try { await axios.post( "http://localhost:9000/api/note/add", addNoteInformation ); } catch (error) { console.error("添加笔记失败:", error); } } };
方案2:直接更新本地状态(优化体验)
在添加/删除成功后直接更新本地状态,减少网络请求,提升响应速度:
- 修改handleAddNote
const handleAddNote = async (tasktext) => { const addNoteInformation = { email: localStorage.getItem("tokenEmail"), taskText: tasktext, date: moment(new Date()).locale("fa").format("YYYY/MM/DD").toString(), }; if (addNoteInformation.email && addNoteInformation.taskText) { try { // 假设后端返回新创建的笔记数据 const response = await axios.post( "http://localhost:9000/api/note/add", addNoteInformation ); setNotes(prevNotes => [...prevNotes, response.data.newNote]); } catch (error) { console.error("添加笔记失败:", error); } } };
- 修改handleDeleteNote
const handleDeleteNote = async (id) => { const deletedInformaion = { email: localStorage.getItem("tokenEmail"), noteId: id, }; if (deletedInformaion.email && deletedInformaion.noteId) { try { await axios.post( "http://localhost:9000/api/note/deleted", deletedInformaion ); setNotes(prevNotes => prevNotes.filter(note => note._id !== id)); } catch (error) { console.error("删除笔记失败:", error); } } };
此时子组件无需再调用getNotes(),可移除相关调用。
内容的提问来源于stack exchange,提问作者sina pouladrag
相关产品推荐
相关产品推荐

