You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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} />;
      })}
    </>
  );
};

问题原因

  1. useEffect未设置依赖数组:Notes组件中的useEffect没有指定依赖数组,会导致组件每次渲染时都执行内部逻辑。
  2. 状态更新触发循环调用: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 04:27:31