You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 00:24:00