如何在React Native的一次fetch调用中设置两个不同的state?
问题梳理
- 重复发起同接口请求:无需两次调用相同接口,单次请求即可同时获取
metadata和features两个字段,重复请求不仅浪费资源,还会导致异步返回时序不可控、loading状态异常 - loading状态逻辑错误:两个请求的
finally都会触发setLoading(false),第一个请求完成就会关闭loading,此时第二个请求可能还未完成,propData还未赋值就触发FlatList渲染,自然报undefined - FlatList数据源绑定错误:
propData存储的是features数组,数组本身没有properties属性,每个数组元素(单个接种点数据)才包含properties字段 - 渲染字段取值错误:
features数组的每个元素是标准GeoJSON结构,接种点的名称、地址等业务字段都存放在properties子对象下,直接取item.name会返回空值
修复方案
步骤1:调整state初始值
将propData的默认值设为空数组,避免渲染阶段出现undefined报错:
// state初始化参考如下结构 const [data, setData] = useState(null); const [propData, setPropData] = useState([]); // 初始为空数组 const [isLoading, setLoading] = useState(true);
步骤2:优化useEffect请求逻辑
单次请求同时为两个state赋值,避免重复请求和时序问题:
useEffect(() => { setLoading(true); // 切换州的时候重置loading状态 fetch(`https://www.vaccinespotter.org/api/v0/states/${stateAbb}.json`) .then((response) => response.json()) .then((json) => { setData(json.metadata); setPropData(json.features); }) .catch((error) => console.error(error)) .finally(() => setLoading(false)); }, [stateAbb]);
步骤3:修正FlatList配置
调整数据源和字段取值逻辑:
{isLoading ? ( <ActivityIndicator /> ) : ( <FlatList data={propData} // 直接用features数组作为数据源 keyExtractor={(item, index) => item.id ?? String(index)} // 无id时用index兜底 renderItem={({ item }) => ( <VaccineRow name={item.properties.name} // 从properties子对象取业务字段 url={item.properties.url} vaccineName={''} enabled={false} address={`${item.properties.address} ${item.properties.city}, ${item.properties.state}`} onPress={() => Linking.openURL(item.properties.url)} /> )} /> )}
内容的提问来源于stack exchange,提问作者ProgrammingMaestro
相关产品推荐
相关产品推荐

