React Native中按Region分组JSON数据后如何循环展示?
Got it, let's walk through this step by step—first we'll transform your raw data into a grouped structure by the region field, then we'll render that grouped data in React Native to match your desired output.
Step 1: Group the Raw Data by Region
First, we need to take your original array of objects and group them using the region value from the dataDetail object. JavaScript's reduce() method is perfect for this kind of aggregation.
Here's a reusable function to handle the grouping:
const groupDataByRegion = (rawData) => { return rawData.reduce((grouped, item) => { const region = item.dataDetail.region; // Create an empty array for the region if it doesn't exist yet if (!grouped[region]) { grouped[region] = []; } // Add the current item to its region's array grouped[region].push(item); return grouped; }, {}); };
Running this with your sample data will output a grouped object matching your "Two JSON" requirement:
{ "aaa": [ { id: 1, status: "active", dataDetail: { id: 5, name: "tes 1", region: "aaa" } } ], "bbb": [ { id: 2, status: "active", dataDetail: { id: 8, name: "tes 2", region: "bbb" } } ] // ... other regions and their associated items }
Step 2: Render the Grouped Data in React Native
Now that we have our grouped data, we can render it with nested loops: first iterate over each region (as a section header), then iterate over each item in that region's list. Below are two common approaches depending on your needs.
Option 1: Using FlatList with Sections (Recommended for Scrollable Lists)
FlatList's sections prop is ideal for grouped data with headers, especially if your list is long and needs scrolling:
import React, { useMemo } from 'react'; import { View, Text, FlatList, StyleSheet } from 'react-native'; const RegionGroupedList = ({ rawData }) => { // Memoize grouped data to avoid recalculating on every render const groupedSections = useMemo(() => { const grouped = groupDataByRegion(rawData); // Convert the grouped object into an array of sections (required by FlatList) return Object.entries(grouped).map(([region, items]) => ({ title: region, data: items, })); }, [rawData]); // Render region section headers const renderSectionHeader = ({ section }) => ( <View style={styles.sectionHeader}> <Text style={styles.headerText}>{section.title}</Text> </View> ); // Render individual items within a region const renderItem = ({ item }) => ( <View style={styles.itemContainer}> <Text>ID: {item.id}</Text> <Text>Name: {item.dataDetail.name}</Text> <Text>Status: {item.status}</Text> </View> ); return ( <FlatList sections={groupedSections} keyExtractor={(item) => item.id.toString()} renderSectionHeader={renderSectionHeader} renderItem={renderItem} /> ); }; const styles = StyleSheet.create({ sectionHeader: { backgroundColor: '#f0f0f0', padding: 12, borderBottomWidth: 1, borderBottomColor: '#ccc', }, headerText: { fontSize: 16, fontWeight: '600', }, itemContainer: { padding: 15, borderBottomWidth: 1, borderBottomColor: '#eee', }, }); export default RegionGroupedList;
Option 2: Using Nested Map (For Small, Non-Scrollable Content)
If your list is short and doesn't need scrolling, you can use nested map() calls directly in your JSX:
import React, { useMemo } from 'react'; import { View, Text, StyleSheet } from 'react-native'; const RegionGroupedView = ({ rawData }) => { const groupedData = useMemo(() => groupDataByRegion(rawData), [rawData]); return ( <View style={styles.container}> {Object.entries(groupedData).map(([region, items]) => ( <View key={region} style={styles.regionSection}> <Text style={styles.regionTitle}>{region}</Text> {items.map((item) => ( <View key={item.id} style={styles.item}> <Text>Name: {item.dataDetail.name}</Text> <Text>Status: {item.status}</Text> </View> ))} </View> ))} </View> ); }; const styles = StyleSheet.create({ container: { padding: 10, }, regionSection: { marginBottom: 20, }, regionTitle: { fontSize: 18, fontWeight: 'bold', marginBottom: 10, }, item: { padding: 8, backgroundColor: '#f8f8f8', marginBottom: 5, borderRadius: 4, }, }); export default RegionGroupedView;
Quick Tips
- Use
useMemoto memoize the grouped data so it only recalculates when therawDataprop changes—this boosts performance. - Always add unique
keyprops to loop-rendered elements (likeregionfor headers anditem.idfor items) to avoid React Native warnings. - Adjust the rendered content and styles to match your exact "Result JSON" needs—just modify the
renderItemor nestedmapcode to display the fields you want.
内容的提问来源于stack exchange,提问作者Quinn

