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

React中如何发起请求并使用Context避免无限循环

解决React组件因Context更新导致的无限重渲染问题

你的问题核心在于useEffect的依赖项设置有误:你依赖了整个recipeCtx,而每次调用setRecipes更新Context时,recipeCtx的引用会发生变化,这会触发useEffect再次执行,进而再次调用setRecipes,形成无限循环。

要实现仅发起一次请求,你可以按以下方式修改:

方案1:仅依赖稳定的更新方法

Context里的setRecipes方法(如果是通过useState创建的)引用是稳定的,不会随Context数据更新而变化,所以把useEffect的依赖项从整个recipeCtx改成recipeCtx.setRecipes即可:

const ContentSidebar = (props) => {
  const recipeCtx = useContext(RecipeContext);

  useEffect(() => {
    const fetchRecipes = async () => {
      const response = await axios(
        "https://react-http-16b52-default-rtdb.firebaseio.com/recipes.json"
      );

      return response.data;
    };

    fetchRecipes().then((recipes) => {
      recipeCtx.setRecipes(recipes);
    });
  }, [recipeCtx.setRecipes]); // 只依赖setRecipes方法

  return (some jsx using recipeCtx.recipes)
};

export default ContentSidebar;

方案2:增加数据存在性判断(可选)

为了避免组件重新挂载时重复请求(比如路由切换后回到该组件),可以再加一层判断,只有当recipes为空时才发起请求:

useEffect(() => {
  // 只有当没有数据时才请求
  if (!recipeCtx.recipes) {
    const fetchRecipes = async () => {
      const response = await axios(
        "https://react-http-16b52-default-rtdb.firebaseio.com/recipes.json"
      );

      return response.data;
    };

    fetchRecipes().then((recipes) => {
      recipeCtx.setRecipes(recipes);
    });
  }
}, [recipeCtx.setRecipes, recipeCtx.recipes]);

这样既遵循了React的依赖项规范,不会出现VSCode的提示,也能保证请求只发起一次。

内容的提问来源于stack exchange,提问作者Tidris

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 01:27:15