为何数据库函数初始返回undefined,刷新页面后才正常?
问题原因及解决方案
你的核心问题是首次渲染时key或type变量未完成初始化,导致readFromDB请求了错误的数据库路径,返回undefined进而触发notOwner判断;刷新页面后变量已获取到正确值,请求路径生效,就能拿到预期数据。同时你的代码还有几个可优化的细节,以下是具体修复方案:
1. 补全readFromDB的返回逻辑
当前函数在snapshot不存在时无显式返回值,默认返回undefined虽然结果符合预期,但显式返回能让逻辑更清晰,避免潜在误解:
async function readFromDB(ID, itemToGrab, type) { const dbRef = ref(getDatabase()); const snapshot = await get( child(dbRef, `users/${type}/${ID}${itemToGrab}`), ); if (snapshot.exists()) { return snapshot.val(); } else { console.log("No data available"); return undefined; // 显式返回undefined,明确逻辑 } }
2. 修正useEffect的依赖项
你的useEffect依赖数组为空,但内部调用的check函数依赖key和type变量。如果这两个变量是异步获取的(比如从路由参数、Firebase Auth获取),首次渲染时它们可能还未赋值(初始为undefined),导致请求路径错误。
解决方法是把key和type加入依赖数组,同时增加前置判断避免无效请求:
useEffect(() => { // 变量未初始化时直接返回,避免错误请求 if (!key || !type) return; const fetchData = async () => { let data = await check(); setResult(data); console.log(data + ' DATA'); }; fetchData(); }, [key, type]); // 添加依赖,确保变量更新时重新执行检查
3. 优化check函数的并发请求
当前两个readFromDB是串行执行的,改成并行执行能提升性能:
async function check() { // 同时发起两个数据库请求 const [pnameResult, petsResult] = await Promise.all([ readFromDB(key, '/Pname', type), readFromDB(key, '/pets', 'dog-walkers') ]); if (pnameResult === undefined && petsResult === undefined) { console.log('user is not actually a owner yet!'); return 'notOwner'; } else { console.log('user is a owner!'); return 'owner'; } }
4. 验证路径正确性(排查用)
可以在readFromDB中打印请求路径,确认首次渲染和刷新时的路径是否一致:
async function readFromDB(ID, itemToGrab, type) { const requestPath = `users/${type}/${ID}${itemToGrab}`; console.log('当前请求路径:', requestPath); // 打印路径 const dbRef = ref(getDatabase()); const snapshot = await get(child(dbRef, requestPath)); if (snapshot.exists()) { return snapshot.val(); } else { console.log("No data available for path:", requestPath); return undefined; } }
如果首次渲染时路径中的ID或type为undefined,就验证了变量初始化延迟的问题,按上述依赖项修正即可。
内容的提问来源于stack exchange,提问作者Jakub Zak
相关产品推荐
相关产品推荐

