React笔记管理:数据更新后UI不刷新,添加依赖触发无限循环
解决React笔记组件更新/删除后UI不刷新的问题
现有代码
获取笔记的API函数
const fetchAllNotes = async () => { try { console.log("Fetching notes..."); const response = await fetch(`${host}/notes/fetchAllNotes`, { method: "GET", headers: { "Content-type": "application/json", "jwt-token": tkn, }, }); const json = await response.json(); console.log(json); return (json); } catch (error) { console.log("Error fetching notes:", error); return ([]); } };
Notes组件代码
import { useContext, useEffect, useState } from "react"; import noteContext from "./noteContext"; import {Container} from 'react-bootstrap' import Noteitem from "./Noteitem"; import AddNote from "./AddNote"; export default function Notes(){ const {fetchAllNotes} = useContext(noteContext); const [notes, setNotes] = useState([]); useEffect(() => { async function getNotes(){ console.log("Use Effect HOOK..."); const data = await fetchAllNotes(); setNotes(data); } getNotes(); }, []); return(<> <AddNote /> <Container> <h2>Your Notes: </h2> <Container className="row my-2"> {notes.map(note =>{ return <Noteitem key={note._id} note={note} />; })} </Container> </Container> </>) }
问题分析
- 初始渲染时
useEffect触发一次,获取笔记并更新notes状态,UI正常渲染。 - 更新/删除笔记后,组件未重新拉取最新数据,导致UI不更新。
- 若将
notes加入useEffect依赖,每次setNotes都会生成新的数组引用,触发useEffect重复执行,形成无限循环。
解决方案
方案1:操作完成后手动刷新数据
找到执行更新/删除笔记的函数(如updateNote、deleteNote),在API请求成功后,直接调用fetchAllNotes更新本地状态。
示例(以删除笔记为例):
const deleteNote = async (noteId) => { // 发起删除请求 await fetch(`${host}/notes/deleteNote/${noteId}`, { method: "DELETE", headers: { "jwt-token": tkn, }, }); // 请求成功后重新获取笔记并更新状态 const latestNotes = await fetchAllNotes(); setNotes(latestNotes); }
方案2:将状态提升到Context统一管理
把notes状态和数据操作逻辑移到noteContext中,所有增删改操作直接在Context内更新状态,组件只需订阅Context中的notes即可自动刷新。
修改Context示例:
import { createContext, useState } from "react"; const noteContext = createContext(); export const NoteProvider = ({ children }) => { const [notes, setNotes] = useState([]); const fetchAllNotes = async () => { try { const response = await fetch(`${host}/notes/fetchAllNotes`, { method: "GET", headers: { "Content-type": "application/json", "jwt-token": tkn, }, }); const json = await response.json(); setNotes(json); // 直接在Context内更新状态 } catch (error) { console.log("Error fetching notes:", error); setNotes([]); } }; const deleteNote = async (id) => { await fetch(`${host}/notes/deleteNote/${id}`, { method: "DELETE", headers: { "jwt-token": tkn, }, }); fetchAllNotes(); // 操作完成后自动刷新数据 }; // 同理实现updateNote、addNote等函数 return ( <noteContext.Provider value={{ notes, fetchAllNotes, deleteNote, updateNote }}> {children} </noteContext.Provider> ); }; export default noteContext;
修改后的Notes组件:
import { useContext, useEffect } from "react"; import noteContext from "./noteContext"; import {Container} from 'react-bootstrap' import Noteitem from "./Noteitem"; import AddNote from "./AddNote"; export default function Notes(){ const { notes, fetchAllNotes } = useContext(noteContext); useEffect(() => { fetchAllNotes(); }, []); return(<> <AddNote /> <Container> <h2>Your Notes: </h2> <Container className="row my-2"> {notes.map(note =>{ return <Noteitem key={note._id} note={note} />; })} </Container> </Container> </>) }
方案3:用useCallback优化函数引用(备选)
若不想迁移状态,可在组件中用useCallback包裹fetchAllNotes,保证引用稳定,同时在操作后手动调用刷新逻辑,但这种方式不如状态集中管理清晰。
为什么加notes到依赖会无限循环?
每次setNotes(data)都会生成新的数组引用,useEffect检测到依赖变化就会重新执行getNotes,再次调用setNotes形成循环。
内容的提问来源于stack exchange,提问作者Shivam Sangwan
相关产品推荐
相关产品推荐

