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
相关产品推荐
相关产品推荐

