如何在React Native Expo应用的config.js中获取并导出Firebase数据
问题解决说明
核心错误原因
- 语法错误:你的
GetData函数未添加闭合的右大括号,且export语句放在了函数内部,ES6规范要求import/export必须放在模块最顶层,不能嵌套在代码块中。 - 逻辑错误:
useState、useEffect是React Hook,只能在React组件函数或自定义Hook内部调用,无法在普通JS模块中直接使用,也不能直接导出Hook内部的状态变量给其他模块调用。 - 耦合问题:你把Firebase初始化逻辑和页面层的状态获取逻辑耦合在了一起,不符合复用要求。
推荐实现方案
方案1:封装自定义Hook(快速复用,适合小项目)
修改后的config.js代码如下:
import "firebase/firestore"; import * as firebase from "firebase"; import { useState, useEffect } from "react"; const firebaseConfig = { apiKey: "<替换为你的Api Key>", authDomain: "<替换为你的AuthDomain>", projectId: "<替换为你的Project Id>", storageBucket: "<替换为你的storage Bucket>", messagingSenderId: "<替换为你的Sender Id>", appId: "<替换为你的App ID>", measurementId: "<替换为你的Measurement ID>", }; // 全局只初始化一次Firebase if (!firebase.apps.length) { firebase.initializeApp(firebaseConfig); } // 导出通用Firebase实例,方便其他自定义逻辑调用 export const firestore = firebase.firestore(); // 封装获取客户数据的自定义Hook export function useCustomerData() { const [CustomerData, setCustomerData] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const fetchData = async () => { try { const querySnapshot = await firestore.collection("CustomerDatabase").get(); const dataList = querySnapshot.docs.map(doc => ({ ...doc.data(), key: doc.id })); setCustomerData(dataList); } catch (err) { setError(err); } finally { setLoading(false); } }; fetchData(); }, []); return { CustomerData, loading, error }; }
在页面中使用方式:
import { useCustomerData } from '../app/config.js'; // 页面组件内部调用 export default function YourPage() { const { CustomerData, loading, error } = useCustomerData(); if (loading) return <Text>数据加载中</Text>; if (error) return <Text>数据加载失败:{error.message}</Text>; // 直接使用CustomerData渲染页面 return ( // 你的页面UI逻辑 ); }
方案2:React Context全局共享(仅请求一次,适合多页面复用,效率更高)
如果要避免每个页面都发起重复的Firebase请求,可以用React Context做全局数据缓存:
- 新建
CustomerDataContext.js文件:
import { createContext, useContext, useEffect, useState } from 'react'; import { firestore } from './config.js'; const CustomerDataContext = createContext(); export function CustomerDataProvider({ children }) { const [CustomerData, setCustomerData] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const fetchData = async () => { try { const querySnapshot = await firestore.collection("CustomerDatabase").get(); const dataList = querySnapshot.docs.map(doc => ({ ...doc.data(), key: doc.id })); setCustomerData(dataList); } catch (err) { setError(err); } finally { setLoading(false); } }; fetchData(); }, []); return ( <CustomerDataContext.Provider value={{ CustomerData, loading, error }}> {children} </CustomerDataContext.Provider> ); } export function useCustomerData() { return useContext(CustomerDataContext); }
- 在入口文件
App.js中全局注入Provider:
import { CustomerDataProvider } from './CustomerDataContext.js'; export default function App() { return ( <CustomerDataProvider> {/* 原有App根组件的所有内容 */} </CustomerDataProvider> ); }
- 所有页面都可以直接调用
useCustomerData()获取数据,全局仅会在App启动时请求一次,无需重复拉取。
内容的提问来源于stack exchange,提问作者RickPeck
相关产品推荐
相关产品推荐

