React Native-Expo中Sanity.io fetch函数无限执行问题求助
问题解决:fetchData无限执行的原因及修复
核心原因
你的代码里useEffect的语法写错了——依赖数组[]被放在了useEffect的括号外面,变成了单独的逗号表达式,这导致useEffect没有正确设置依赖,每次组件渲染都会重新执行fetchData,进而无限发起API请求。
修复方案
1. 仅在页面加载时执行一次
把依赖数组移到useEffect的第二个参数位置,这样useEffect只会在组件挂载时执行一次:
import { View } from "react-native"; import React, { useState, useEffect } from "react"; import Memory from "../component/Memory"; import sanityclient from "../memories-20/sanityclient"; const Memories = () => { const [memories, setMemories] = useState([]); const [isLoading, setIsLoading] = useState(true); const [startIndex, setStartIndex] = useState(0); const batchOfMemories = memories.slice(startIndex, startIndex + 3); const fetchData = () => { sanityclient .fetch( `*[_type == "memory"] | order(date desc) { ..., }` ) .then((data) => { setMemories(data); setIsLoading(false); }); }; // 修正useEffect的语法,把依赖数组放在第二个参数位置 useEffect(() => { fetchData(); }, []); // 空数组表示仅在组件挂载时执行一次 return ( <View className="flex-1 items-center bg-transparent justify-center"> <View> <View className="flex items-center w-full h-[90%]"> {!isLoading ? ( <View> {batchOfMemories.map((memory, index) => ( <Memory key={index} {...memory} /> ))} </View> ) : ( <View>Loading...</View> {/* 替换为你的实际Loading组件 */} )} </View> </View> </View> ); }; export default Memories;
2. 仅在特定条件变化时执行
如果需要在某个状态变化时重新请求数据(比如后续要做下拉刷新、筛选等场景),可以把对应状态加入依赖数组,这样只有当该状态改变时才会重新执行fetchData:
// 示例:当startIndex变化时重新请求数据 useEffect(() => { fetchData(); }, [startIndex]);
额外优化点
map循环里必须给Memory组件设置唯一key(优先用记忆项的唯一ID,没有的话用循环索引),同时要把memory数据传递给组件,否则无法正确渲染每个记忆项。setMemories是异步操作,直接在它后面console.log(memories)会拿到更新前的旧值,如果需要查看更新后的记忆数据,可以新增一个监听memories变化的useEffect。
内容的提问来源于stack exchange,提问作者Putra Amir
相关产品推荐
相关产品推荐

