React Native中useEffect调用API产生无限循环如何解决
无限循环根因
你当前的useEffect依赖设置为renderArr,而useEffect内部执行的getStatus函数最后会调用setRenderArr修改renderArr的值,形成「renderArr更新 → 触发useEffect执行 → 调用setRenderArr更新renderArr → 再次触发useEffect」的死循环。
除此之外你的代码还有几处语法错误需要修正:
getStatus内部定义的源数组叫arr,合并数据时用了未声明的newArr,需改为arr.map- 渲染部分遍历的
mergedArray是getStatus的内部局部变量,组件作用域无法访问,需改为遍历状态renderArr - 数组内的
Leather、Shoe、Belt是字符串值,缺少引号包裹
修复方案
首先明确:renderArr作为组件state,本身值变化就会自动触发组件重新渲染,不需要把它放到useEffect的依赖项中实现重渲染逻辑。
方案1:仅组件初始化时拉取接口
如果接口只需要在组件挂载完成后调用一次,把useEffect的依赖改为空数组即可:
useEffect(() => { getStatus(); }, []); // 空数组代表仅组件挂载后执行一次
方案2:按业务触发条件重新拉取接口
如果有其他触发接口刷新的场景(比如props.token变化、用户手动刷新),把对应的触发源加到useEffect依赖中即可,比如token变更时重新拉取:
useEffect(() => { getStatus(); }, [props.token]);
方案3:确实需要监听renderArr变化时拉取接口的处理
如果你的业务逻辑要求renderArr变化时必须重新调用接口更新数据,可以在更新状态前加一层数据对比,只有数据真实变化时才更新状态,避免死循环:
const getStatus= async() =>{ const arr = [ {id: 1,name: 'Leather'}, {id: 2,name: 'Shoe'}, {id: 3,name: 'Belt'}, ] const firstStatus = await API(arr[0].id , props.token) const secondStatus = await API(arr[1].id , props.token) const thirdStatus = await API(arr[2].id , props.token) const statusObj = [ { status: firstStatus.status }, { status: secondStatus.status }, { status: thirdStatus.status }, ] const mergedArray = arr.map((e, i) => ({ ...e, ...statusObj[i] })); // 对比新老数据,一致则不更新状态 const isDataEqual = mergedArray.every((item, index) => { return renderArr[index] && JSON.stringify(item) === JSON.stringify(renderArr[index]) }) if (!isDataEqual) { setRenderArr(mergedArray); } }
修复渲染代码
把渲染部分的遍历变量改为renderArr,同时给遍历项加key属性避免React警告:
return ( <View style={styles.container}> {renderArr.map((item, index) => { return ( <TouchableOpacity key={index}> <Text style={{ color: '#FFF' }}>{item.status}</Text> </TouchableOpacity> ); })} </View> );
内容的提问来源于stack exchange,提问作者Wedevs Mobileapp
相关产品推荐
相关产品推荐

