React Native中useState赋值后引用JSON字段报错的优化问询
解决React Native中API数据加载前的空值报错问题
核心问题分析
你遇到的报错本质是组件渲染时序问题:初始状态下flightResponse为null,而组件首次渲染时API请求还未完成,此时访问flightResponse.type或调用map方法,自然会因null不具备这些属性/方法而报错。下面是几种更简洁、健壮的处理方案:
优化方案一:匹配数据类型的初始状态
既然API返回的是数组类型的数据,直接将初始状态设为空数组[]是最合理的选择——空数组可以直接调用map方法(不会报错),无需额外的空值判断:
// 初始值设为空数组 const [flightResponse, setFlightResponse] = useState([]);
对应的JSX可以简化为:
<ScrollView style={{marginTop: 220}}> {flightResponse.map(data => ( <FlightCard key={data.id} data={data} onPress={() => {}} /> ))} </ScrollView>
这种方案最简洁,完全贴合数据的实际类型,避免了冗余判断。
优化方案二:可选链操作符安全访问
如果因业务需求需要保留初始值为null,可以使用ES6的可选链操作符?.来安全访问属性和方法,它会在左侧值为null/undefined时自动停止执行,返回undefined而非抛出错误:
// 安全访问type字段 console.log("TEST: ", flightResponse?.type);
JSX中同样适用:
<ScrollView style={{marginTop: 220}}> {flightResponse?.map(data => ( <FlightCard key={data.id} data={data} onPress={() => {}} /> ))} </ScrollView>
此方案灵活性高,适合不确定返回数据类型的场景。
优化方案三:增加加载状态提升体验
在API请求过程中添加加载状态,既能避免空值渲染,又能给用户明确的反馈,同时还能处理请求失败的情况:
const [flightResponse, setFlightResponse] = useState([]); const [isLoading, setIsLoading] = useState(true); useEffect(() => { const fetchFlightData = async () => { try { const data = await searchFlightOffers(postData); setFlightResponse(data.data); } catch (err) { console.error("航班数据获取失败:", err); // 可在这里添加错误提示逻辑 } finally { setIsLoading(false); } }; fetchFlightData(); }, []);
对应的JSX:
<ScrollView style={{marginTop: 220}}> {isLoading ? ( <Text style={{textAlign: 'center', padding: 20}}>加载中...</Text> ) : ( flightResponse.map(data => ( <FlightCard key={data.id} data={data} onPress={() => {}} /> )) )} </ScrollView>
API函数的可读性优化
你当前的API函数使用了嵌套then,可以改用async/await让代码结构更清晰,同时统一处理错误:
export async function searchFlightOffers(postData) { try { const tokenData = await getAmadeusToken(); const config = { headers: { 'Authorization': `Bearer ${tokenData.access_token}` } }; const response = await axios.post( "https://test.api.amadeus.com/v2/shopping/flight-offers", postData, config ); return response.data; // 直接返回data,组件无需再取data.data } catch (err) { console.error("获取航班报价失败:", err); throw err; // 抛出错误让组件层处理 } }
内容的提问来源于stack exchange,提问作者enki
相关产品推荐
相关产品推荐

