React中fetchNotes函数重复调用的原因及解决方案
问题:fetchNotes重复调用问题分析与解决
问题现象
调用setNotes更新notes状态时,fetchNotes函数会重复执行;若跳过setNotes操作,则无此问题。
相关代码
状态管理中的fetchNotes实现
const [notes, setNotes] = useState(notesInitial); //fetch notes const fetchNotes = async () => { const response = await fetch( "http://localhost:5500/api/notes/fetchallnotes", { method: "GET", // *GET, POST, PUT, DELETE, etc. headers: { "Content-Type": "application/json", "auth-token": localStorage.getItem("token"), }, } ); const json = await response.json(); setNotes(json); console.log("Running Fetch all notes"); };
Notes组件代码
const Notes = () => { const context = useContext(noteContext); const { notes, fetchNotes } = context; let navigate = useNavigate(); useEffect(() => { if (localStorage.getItem("token")) { fetchNotes(); } else { navigate("/login"); } }); // console.log(notes); return ( <> <h2>All Notes</h2> {notes.length === 0 && "No notes. Created note will appear here"} {notes.map((note) => { return <NoteItems note={note} key={note._id} />; })} </> ); };
问题原因
- useEffect未设置依赖数组:Notes组件中的
useEffect没有指定依赖数组,会导致组件每次渲染时都执行内部逻辑。 - 状态更新触发循环调用:
fetchNotes调用setNotes更新notes状态后,组件会因状态变化重新渲染;重新渲染又会触发useEffect再次调用fetchNotes,形成循环:useEffect调用fetchNotes → setNotes更新状态 → 组件重新渲染 → useEffect再次调用fetchNotes。
解决方案
基础修复:添加空依赖数组
给useEffect添加空依赖数组,确保它仅在组件挂载时执行一次:
useEffect(() => { if (localStorage.getItem("token")) { fetchNotes(); } else { navigate("/login"); } }, []); // 添加空依赖数组
进阶优化:确保fetchNotes引用稳定
如果fetchNotes是从Context中获取的,建议在状态管理中用useCallback包裹它,避免因引用变化导致的重复执行:
// 在Context的Provider中处理fetchNotes const fetchNotes = useCallback(async () => { const response = await fetch( "http://localhost:5500/api/notes/fetchallnotes", { method: "GET", headers: { "Content-Type": "application/json", "auth-token": localStorage.getItem("token"), }, } ); const json = await response.json(); setNotes(json); console.log("Running Fetch all notes"); }, []); // 若token动态变化,需将token加入依赖数组
之后在Notes组件的useEffect中加入稳定的fetchNotes作为依赖:
useEffect(() => { const token = localStorage.getItem("token"); if (token) { fetchNotes(); } else { navigate("/login"); } }, [navigate, fetchNotes]);
内容的提问来源于stack exchange,提问作者Subhodip Roy
相关产品推荐
相关产品推荐

