如何使用Axios请求三个API并在React Native的FlatList中正确渲染所需数据?
Fixing FlatList Rendering with Multiple API Responses in React Native
Hey there, let's work through this issue together! I see two main problems with your current code that are preventing your FlatList from rendering correctly, and we'll fix them step by step.
What's Going Wrong?
- You're trying to return JSX directly from an event handler: The
Fetchfunction is triggered by a button press, but React doesn't render JSX returned from event callbacks. Instead, you need to store your API data in component state and let React re-render when that state updates. - You're using full axios response objects instead of the actual data: Each item in the
responsesarray is a complete axios response (with properties likedata,status,headers), not the raw data your API sends back. You need to extract thedataproperty from each response first.
Step-by-Step Solution
1. Add State to Store Your API Data
First, import useState from React and initialize a state variable to hold your combined API data:
import { useState } from 'react'; // ... rest of your imports const App = () => { const [apiData, setApiData] = useState([]); // Initialize empty array // ... rest of your code }
2. Update the Fetch Function to Extract Data and Update State
Modify your Fetch function to extract the actual data from each response and update the state. We'll also use Promise.all (which axios.all is an alias for) for cleaner code:
const Fetch = async () => { try { const one = "EXAMPLEAPI"; const two = "EXAMPLEAPI"; const three = "EXAMPLEAPI"; // Fetch all requests in parallel const responses = await Promise.all([ axios.get(one), axios.get(two), axios.get(three) ]); // Extract the data from each response const combinedData = responses.map(response => response.data); // Update state with the cleaned data setApiData(combinedData); } catch (errors) { console.error('Error fetching data:', errors); } }
3. Render FlatList Using the State Data
Now, render your FlatList outside the event handler, using the apiData state. We'll also add a loading/empty state for better UX:
return ( <SafeAreaView> <Text>PRESS</Text> <TouchableOpacity onPress={Fetch} > <Text>HERE</Text> </TouchableOpacity> {/* Render FlatList only when we have data */} {apiData.length > 0 ? ( <FlatList keyExtractor={item => item.title} // Make sure each item has a unique title! data={apiData} renderItem={({ item }) => { return <Text>{item.title}</Text>; }} /> ) : ( <Text>No data yet - press "HERE" to fetch!</Text> )} </SafeAreaView> );
Full Modified Code
Here's the complete working code:
import React, { useState } from 'react'; import { SafeAreaView, Text, TouchableOpacity, FlatList } from 'react-native'; import axios from 'axios'; const App = () => { const [apiData, setApiData] = useState([]); const Fetch = async () => { try { const one = "EXAMPLEAPI"; const two = "EXAMPLEAPI"; const three = "EXAMPLEAPI"; const responses = await Promise.all([ axios.get(one), axios.get(two), axios.get(three) ]); const combinedData = responses.map(res => res.data); setApiData(combinedData); } catch (errors) { console.error('Fetch error:', errors); } }; return ( <SafeAreaView> <Text>PRESS</Text> <TouchableOpacity onPress={Fetch} > <Text>HERE</Text> </TouchableOpacity> {apiData.length > 0 ? ( <FlatList keyExtractor={item => item.title} data={apiData} renderItem={({ item }) => <Text>{item.title}</Text>} /> ) : ( <Text>Tap "HERE" to load data</Text> )} </SafeAreaView> ); }; export default App;
Important Notes
- Double-check that each API response's
dataobject actually has atitleproperty. If not, adjust therenderItemandkeyExtractorto match your actual data structure. - Using
async/awaitmakes the code more readable than chaining.then()calls, which is why we switched to that syntax. - Always handle loading and empty states to give users clear feedback about what's happening.
内容的提问来源于stack exchange,提问作者Florin
相关产品推荐
相关产品推荐

