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

Expo中如何正确展示Firebase快照数据?解决系列渲染错误

问题解决:Expo中Firebase单节点数据展示错误修正

错误原因分析

1. 初始代码错误:Snapshot cannot be found

  • snapshot是onValue回调内的局部变量,组件return的JSX作用域无法访问它。
  • 直接将Firebase的Snapshot对象存入state不合理,React无法直接渲染这类特殊对象。

2. 修改后错误:Objects are not valid as a React child & TypeError: undefined is not a function

  • snapshot.val()返回的是单个对象(从控制台日志可看出是单个美食节点的数据),不是数组,直接渲染对象会触发React子元素类型错误。
  • 对单个对象调用map方法必然失败,因为map是数组专属方法,对象没有该方法。

修正后的代码

const SubScreen3 = ({ route }) => {
  const paramKey = route.params.paramKey1
  // 初始化state为包含节点key和数据的对象,而非数组
  const [todoData, setToDoData] = useState({ key: '', data: {} })

  useEffect(() => {
    const starCountRef = ref(db, "food/" + paramKey);
    const unsubscribe = onValue(starCountRef, (snapshot) => {
      // 同时保存节点key和数据到state
      setToDoData({
        key: snapshot.key,
        data: snapshot.val() || {} // 处理数据为空的情况
      })
    })

    // 组件卸载时取消监听,避免内存泄漏
    return () => unsubscribe()
  }, [paramKey]) // 添加paramKey到依赖数组,确保参数变化时重新监听

  // 解构数据,方便后续使用
  const { key, data } = todoData

  return (
    <View style={styles.container}>
      {/* 直接渲染单个节点的属性 */}
      <Text style={styles.header}>{key}</Text>
      <Text style={styles.header}>{data.Description}</Text>
      <Text style={styles.header}>{data.Location}</Text>
      <Text style={styles.header}>{data.OH}</Text>
      <Text style={styles.header}>{data.Halal ? "Halal" : "Non-Halal"}</Text>

      <TouchableOpacity
        // onPress={() => navigation.navigate("SubScreen1", { paramKey: key })}
        style={styles.button}
      >
        <Text style={styles.buttonText}>How to go?</Text>
      </TouchableOpacity>

      <TouchableOpacity
        // onPress={() => {/* 跳转评论页逻辑 */}}
        style={styles.button}
      >
        <Text style={styles.buttonText}>Reviews</Text>
      </TouchableOpacity>
    </View>
  )
}

export default SubScreen3

关键修正点

  • State结构调整:将state改为存储包含节点key和数据对象的结构,匹配Firebase单节点数据的格式。
  • 作用域问题解决:通过state传递数据,避免在JSX中直接访问回调内的局部变量。
  • 添加监听清理:在useEffect的返回函数中取消Firebase监听,防止组件卸载后内存泄漏。
  • 数据安全处理:使用snapshot.val() || {}避免数据未加载时访问undefined属性。
  • 直接渲染属性:因为是单个节点数据,无需使用map,直接访问对象属性即可渲染。

内容的提问来源于stack exchange,提问作者L.Calvin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 13:55:38