如何显示ActivityIndicator直至所有设备元素完成map映射渲染
解决方案
核心逻辑是监听每个设备子项的渲染完成事件,所有子项都渲染完毕后再关闭加载动画,修改方案如下:
具体修改点
- 拉取到设备数据后仅更新设备列表状态,不立即关闭加载态
- 为每个渲染的设备子项添加
onLayout回调,统计已完成渲染的子项数量 - 当已渲染子项数等于设备总数量时,再将
isLoading设为false关闭加载动画 - 额外适配设备列表为空的边界场景
修改后完整代码
import { useState, useEffect } from 'react'; import { View, Text, ActivityIndicator } from 'react-native'; const MyScreen = () => { const [devices, setDevices] = useState([]); const [isLoading, setIsLoading] = useState(true); const [renderedCount, setRenderedCount] = useState(0); useEffect(() => { getDevices(); }, []); // 监听设备列表变化,处理边界场景和计数重置 useEffect(() => { // 设备列表为空时直接关闭加载 if (devices.length === 0) { setIsLoading(false); } // 设备列表更新时重置渲染计数 setRenderedCount(0); }, [devices]); const getDevices = async () => { const pulledDevices = await fetchDevices(); setDevices(pulledDevices); // 移除原有的setIsLoading(false)逻辑 }; if (isLoading) { return <ActivityIndicator />; } return ( <View> {devices.map((device, index) => { return ( <View // 请替换为设备的唯一标识作为key key={device.id} onLayout={() => { setRenderedCount(prev => { const newCount = prev + 1; // 所有子项渲染完成后关闭加载 if (newCount === devices.length) { setIsLoading(false); } return newCount; }); }} > <Text>{device.name}</Text> </View> ); })} </View> ); };
可选优化(长列表场景)
如果设备列表长度较大,更推荐使用FlatList组件实现,性能远高于手动map渲染,同时可以直接通过FlatList的onContentSizeChange回调判断列表整体渲染完成,无需手动计数:
// 仅需替换return部分的逻辑即可 if (isLoading) { return <ActivityIndicator />; } return ( <FlatList data={devices} keyExtractor={item => item.id} renderItem={({item}) => ( <View> <Text>{item.name}</Text> </View> )} onContentSizeChange={() => setIsLoading(false)} /> );
内容的提问来源于stack exchange,提问作者Vladimír
相关产品推荐
相关产品推荐

