React Native无法访问Firestore返回数据的二级属性
Firestore嵌套属性访问报错解决方案
问题场景
详情页面获取Firestore文档,结构如下:
{ "category": { "id": "3", "name": "Concerts", }, "date": { "end": { "nanoseconds": 543000000, "seconds": 1660705200, }, "start": { "nanoseconds": 49000000, "seconds": 1660698000, }, }, "title": "Gravity Funk", }
页面能正常渲染title,但访问category.name时抛出错误:
TypeError: undefined is not an object (evaluating 'event.category.name')
之前列表页用FlatList的renderItem能正常处理嵌套属性,但详情页不知道如何解决。
问题代码
import React, {useState, useEffect, Component} from 'react'; import { StyleSheet, Text, View, TouchableOpacity, ScrollView, Image, Dimensions } from 'react-native'; import { initializeApp } from 'firebase/app'; import { getFirestore, doc, getDoc } from 'firebase/firestore'; const firebaseConfig = {...}; const app = initializeApp(firebaseConfig); const db = getFirestore(app); const EventScreen = ({route, navigation}) => { let category; const eventId = route.params.eventId; const [event, setEvent] = useState([]); const getEvent = async (dbx) => { let isMounted = true; const eventDoc = doc(dbx, 'events', eventId); const eventSnapshot = await getDoc(eventDoc); const fetchedEvent = eventSnapshot.data(); setEvent(fetchedEvent); return fetchedEvent; } useEffect(() => { getEvent(db); },[]) return ( <View> <Text>{event.title}</Text> <Text>{event.category.name}</Text> </View> ) }
问题原因
- 初始状态不匹配:
event初始值设为数组[],但实际获取的是对象。首次渲染时event.category为undefined,访问name自然报错。 - 异步加载时序:组件首次渲染时,异步的
getEvent还未完成,event仍为初始值,此时访问嵌套属性必然失败。
解决方法
1. 可选链操作符(最简洁)
在嵌套属性前添加?.,当属性不存在时自动返回undefined,不会抛出错误:
<Text>{event.category?.name}</Text>
2. 条件渲染
先判断event.category是否存在,再渲染对应内容:
{event.category && <Text>{event.category.name}</Text>}
3. 修正初始状态
将event的初始值设为包含空category的对象,确保渲染时嵌套属性路径存在:
const [event, setEvent] = useState({ category: {} });
额外优化点
- 给
useEffect添加依赖项[eventId],避免组件重复渲染时不必要地调用getEvent。 - 获取文档时增加存在性判断,防止文档不存在时设置
undefined到state:
const getEvent = async (dbx) => { const eventDoc = doc(dbx, 'events', eventId); const eventSnapshot = await getDoc(eventDoc); if (eventSnapshot.exists()) { setEvent(eventSnapshot.data()); } }
内容的提问来源于stack exchange,提问作者Noisemastering
相关产品推荐
相关产品推荐

