React Native如何从两个不同URL fetch JSON数据并匹配相同ID?
React Native 双数据源ID匹配筛选实现(函数式组件)
以下是完整实现代码,基于React Hooks完成并发请求、ID匹配、状态处理全流程:
import React, { useState, useEffect } from 'react'; import { View, Text, ActivityIndicator, FlatList, StyleSheet } from 'react-native'; const MatchedDataScreen = () => { // 状态定义 const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [matchedFellowships, setMatchedFellowships] = useState([]); useEffect(() => { const fetchAndMatchData = async () => { try { // 并发请求两个数据源,减少等待时间 const [fellowshipsRes, mobileRes] = await Promise.all([ fetch('https://mobile.xa-speakers.org/fellowships.json'), fetch('https://mobile.xa-speakers.org/mobile.json') ]); // 解析JSON响应 const fellowshipsData = await fellowshipsRes.json(); const mobileData = await mobileRes.json(); // 提取数据源2的所有ID存入Set,匹配时时间复杂度为O(1),性能更高 const mobileIdSet = new Set(mobileData.map(item => item.id)); // 筛选数据源1中ID存在于数据源2的条目 const matchedData = fellowshipsData.filter(item => mobileIdSet.has(item.id)); setMatchedFellowships(matchedData); } catch (err) { setError(err.message || '数据请求或处理失败'); } finally { setLoading(false); } }; fetchAndMatchData(); }, []); // 加载状态渲染 if (loading) { return ( <View style={styles.centerContainer}> <ActivityIndicator size="large" color="#2196F3" /> <Text style={styles.loadingText}>数据加载中...</Text> </View> ); } // 错误状态渲染 if (error) { return ( <View style={styles.centerContainer}> <Text style={styles.errorText}>错误:{error}</Text> </View> ); } // 匹配结果渲染 return ( <View style={styles.container}> <Text style={styles.title}>匹配到的条目共 {matchedFellowships.length} 条</Text> <FlatList data={matchedFellowships} keyExtractor={item => item.id.toString()} renderItem={({ item }) => ( <View style={styles.itemCard}> <Text style={styles.itemTitle}>ID:{item.id}</Text> {/* 可根据实际返回字段调整展示内容 */} <Text style={styles.itemContent}>名称:{item.name || '无'}</Text> </View> )} /> </View> ); }; // 样式定义 const styles = StyleSheet.create({ centerContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20, }, container: { flex: 1, padding: 16, backgroundColor: '#f5f5f5', }, loadingText: { marginTop: 12, fontSize: 14, color: '#666', }, errorText: { fontSize: 14, color: '#f44336', textAlign: 'center', }, title: { fontSize: 18, fontWeight: 'bold', marginBottom: 16, color: '#333', }, itemCard: { backgroundColor: '#fff', padding: 16, borderRadius: 8, marginBottom: 12, shadowColor: '#000', shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.1, shadowRadius: 2, elevation: 2, }, itemTitle: { fontSize: 16, fontWeight: '500', color: '#333', marginBottom: 4, }, itemContent: { fontSize: 14, color: '#666', }, }); export default MatchedDataScreen;
注意事项
- 代码默认两个数据源的唯一标识字段均为
id,如果实际返回字段名不同,修改map和filter方法里对应的字段名即可 - 采用
Promise.all并发请求时,任意一个接口请求失败都会进入错误捕获逻辑,如果需要兼容单个接口失败仍可处理另一个接口数据的场景,可以替换为Promise.allSettled自行处理每个请求的状态 - 列表的展示字段可根据接口实际返回的业务字段自行调整
内容的提问来源于stack exchange,提问作者Kaj
相关产品推荐
相关产品推荐

