React Query结合Firebase获取数据返回undefined求助(Next.js12)
问题原因及解决方案
核心问题梳理
- Hook调用规则违反:
useQuery是React Hook,必须在组件或自定义Hook的顶层执行,不能嵌套在异步函数内部。 - 数据收集逻辑错误:
snapshot.forEach()没有返回值,调用它的结果是undefined,导致useQuery无法获取有效数据,应该用map()来收集文档数据。 - Hook命名不规范:React Hook必须以小写
use开头,UseAuth应改为useAuth。 - 配置项传递错误:
useQuery的配置参数被拆成了两个独立对象,需要合并为一个对象传入。 - 自定义Hook写法错误:
usePortfolio中直接赋值fetchDbData,既没有调用函数,也不符合自定义Hook的编写规范。 - 拼写错误:
_app.js中的useInfiniteQury是笔误,正确应为useInfiniteQuery。
修正后的代码示例
自定义Hook文件(获取并渲染数据的文件)
import { useAuth } from './path-to-your-auth-hook'; // 替换为实际的auth hook路径 import { query, collection, getDocs } from 'firebase/firestore'; import { useQuery } from '@tanstack/react-query'; // 封装Firebase数据获取逻辑为异步函数 const fetchFirebaseData = async () => { const { currentUser } = useAuth(); // 简化路径判断逻辑 const loc = currentUser ? `users/${currentUser.uid}/userInvestments` : 'users/TestDocumentForDatabase/userInvestments'; const q = query(collection(db, loc)); const snapshot = await getDocs(q); // 用map收集文档数据,保留文档ID(可选) return snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); }; // 符合规范的自定义Hook export default function usePortfolio() { // 在Hook顶层调用useQuery const { data, status, error } = useQuery( ['firebaseData'], // 查询唯一标识键 fetchFirebaseData, // 异步查询函数 { refetchOnWindowFocus: false, retry: false } // 合并所有配置项到一个对象 ); return { data, status, error }; }
_app.js修正
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { AuthProvider } from './path-to-your-auth-provider'; // 替换为实际的AuthProvider路径 import RootLayout from './path-to-your-root-layout'; // 替换为实际的RootLayout路径 export const queryClient = new QueryClient({ defaultOptions: { queries: { refetchOnWindowFocus: false, useInfiniteQuery: false, // 修正拼写错误 }, } }); export default function App({ Component, pageProps }) { return ( <QueryClientProvider client={queryClient}> <AuthProvider> <RootLayout> <Component {...pageProps} /> </RootLayout> </AuthProvider> </QueryClientProvider> ); }
额外说明
- 确保
db是已正确初始化的Firebase Firestore实例,项目已完成Firebase基础配置。 - 自定义Hook必须以
use开头,这是React的强制规范,确保React能识别并应用Hook的规则。 useQuery的查询函数必须返回Promise,修正后的fetchFirebaseData符合该要求。
内容的提问来源于stack exchange,提问作者Dotman
相关产品推荐
相关产品推荐

