React Native从Firestore取数据遇组件类型无效错误求助
React Native + Firestore 报错:Element type is invalid 解决方法
错误信息
ERROR Error: Element type is invalid: expected a string
(for built-in components) or a class/function (for composite components) but got: object.
Check the render method ofFetchData.
问题背景
在使用React Native从Firebase Firestore获取数据时出现上述错误,已在Firebase中创建baghdad集合,Firebase配置看似正常,但报错依旧。相关代码如下:
原FetchData.js代码
import { View, StyleSheet } from "react-native"; import React from "react"; import firebase from "firebase/compat/app"; import "firebase/compat/auth"; import "firebase/compat/firestore"; const firebaseConfig = { apiKey: "", authDomain:"-.m", projectId: "-", storageBucket: "-..", messagingSenderId: "", appId: "", }; const firebaseApp = firebase.initializeApp(firebaseConfig); const db = firebaseApp.firestore(); const auth = firebase.auth(); if (!firebase.apps.length) { firebase.initializeApp(firebaseConfig); } import { Component } from "react"; import { ScrollView, ActivityIndicator } from "react-native"; import { List } from "react-native-paper"; export { auth, db }; class FetchData extends Component { constructor() { super(); this.docs = firebase.firestore().collection("baghdad"); this.state = { isLoading: true, baghdad: [], }; } componentDidMount() { this.unsubscribe = this.docs.onSnapshot(this.getStudentsData); } componentWillUnmount() { this.unsubscribe(); } getStudentsData = (querySnapshot) => { const baghdad = []; querySnapshot.forEach((res) => { const { name, business_status } = res.data(); baghdad.push({ key: res.place_id, name, business_status, }); }); this.setState({ baghdad, isLoading: false, }); }; render() { if (this.state.isLoading) { return ( <View style={styles.loader}> <ActivityIndicator size="large" color="red" /> </View> ); } return ( <ScrollView style={styles.wrapper}> {this.state.baghdad.map((res, i) => { return ( <List key={i} bottomDivider> <List.Content> <List.Title>{res.name}</List.Title> <List.Subtitle>{res.business_status}</List.Subtitle> </List.Content> <List.Chevron color="black" /> </List> ); })} </ScrollView> ); } } const styles = StyleSheet.create({ wrapper: { flex: 1, paddingBottom: 22, }, loader: { position: "absolute", alignItems: "center", justifyContent: "center", left: 0, right: 0, top: 0, bottom: 0, }, }); export default FetchData;
原App.js代码
import React from "react"; import FetchData from "./src/FetchData"; export default function App() { return <FetchData />; }
问题分析与修复方案
1. 核心错误:react-native-paper List组件用法错误
当前版本的react-native-paper中,不存在List.Content、List.Title、List.Chevron这类子组件写法,React无法识别这些引用,因此抛出"Element type is invalid"错误。需要改用库提供的标准列表组件结构。
2. 次要问题:Firebase重复初始化
代码中执行了两次Firebase初始化操作,会触发不必要的警告,需调整逻辑确保只初始化一次。
修正后的FetchData.js代码
import { View, StyleSheet, ScrollView, ActivityIndicator } from "react-native"; import React, { Component } from "react"; import firebase from "firebase/compat/app"; import "firebase/compat/auth"; import "firebase/compat/firestore"; import { List } from "react-native-paper"; const firebaseConfig = { apiKey: "", authDomain:"-.m", projectId: "-", storageBucket: "-..", messagingSenderId: "", appId: "", }; // 确保Firebase只初始化一次 if (!firebase.apps.length) { firebase.initializeApp(firebaseConfig); } const db = firebase.firestore(); const auth = firebase.auth(); export { auth, db }; class FetchData extends Component { constructor() { super(); this.docs = db.collection("baghdad"); this.state = { isLoading: true, baghdad: [], }; } componentDidMount() { this.unsubscribe = this.docs.onSnapshot(this.getStudentsData); } componentWillUnmount() { this.unsubscribe(); } getStudentsData = (querySnapshot) => { const baghdad = []; querySnapshot.forEach((res) => { const { name, business_status } = res.data(); baghdad.push({ key: res.id, // Firestore文档默认ID为res.id,若需place_id请确保文档中存在该字段 name, business_status, }); }); this.setState({ baghdad, isLoading: false, }); }; render() { if (this.state.isLoading) { return ( <View style={styles.loader}> <ActivityIndicator size="large" color="red" /> </View> ); } return ( <ScrollView style={styles.wrapper}> <List.Section> {this.state.baghdad.map((res) => { return ( <List.Item key={res.key} title={res.name} subtitle={res.business_status} right={() => <List.Icon icon="chevron-right" color="black" />} bottomDivider /> ); })} </List.Section> </ScrollView> ); } } const styles = StyleSheet.create({ wrapper: { flex: 1, paddingBottom: 22, }, loader: { position: "absolute", alignItems: "center", justifyContent: "center", left: 0, right: 0, top: 0, bottom: 0, }, }); export default FetchData;
关键修改说明
- Firebase初始化:调整为
if (!firebase.apps.length)判断后再初始化,避免重复操作;直接使用初始化后的db实例获取集合。 - List组件用法:改用
List.Section包裹列表,使用List.Item定义每个列表项,通过title、subtitle属性设置文本,用right属性添加右侧箭头图标。 - 文档ID修正:将
res.place_id改为res.id(Firestore默认文档ID),若需自定义place_id请确保文档中存在该字段。
App.js无需修改
保持原App.js代码即可正常运行。
内容的提问来源于stack exchange,提问作者Yaseen Aiman Mohammed
相关产品推荐
相关产品推荐

