如何在异步函数执行完成后再渲染页面?React Native显示NaN问题
问题描述

我编写了如下代码:
const WalletScreen = () => { const checkBalance = async () => { const docRef = doc(db, "users", auth.currentUser.uid); const docSnap = await getDoc(docRef); let tempBalance; if (docSnap.exists()) { const notFirstRun = docSnap.data().notFirstRun; if (notFirstRun) { Wbalance = docSnap.data().WalletBalance; } else { tempBalance = 1000000; await setDoc( docRef, { WalletBalance: tempBalance, notFirstRun: true }, { merge: true } ).catch((error) => { alert(error.message); }); } } return tempBalance; }; let displayBalance = checkBalance(); return ( <View style={{ backgroundColor: "white", alignItems: "center" }}> <Text style={{ fontSize: 42, marginVertical: 30 }}> K{(displayBalance / 100)} </Text> </View> ); };
我通过checkBalance函数实现余额展示逻辑:首次运行App时,将余额tempBalance设为1000000并保存至Firestore;非首次运行则从Firestore读取余额。我使用displayBalance变量展示余额,本以为async/await会在页面渲染前完成执行,但实际显示NaN,请帮忙指出错误所在。
错误分析与修复方案
1. Async函数返回Promise而非直接数值
checkBalance是async函数,调用后会直接返回Promise对象,不是你期望的余额数值。直接对Promise执行displayBalance / 100运算,必然得到NaN。
2. 非首次运行时tempBalance未赋值
非首次运行时,代码仅给未定义的Wbalance赋值,tempBalance仍为初始的undefined,函数返回undefined后参与计算也会得到NaN。
3. 未使用React状态管理余额
组件渲染不会等待async函数执行完成,必须用React状态存储余额,异步操作完成后更新状态触发组件重新渲染,才能展示正确数值。
修复后的代码
import { useState, useEffect } from 'react'; const WalletScreen = () => { const [displayBalance, setDisplayBalance] = useState(null); const checkBalance = async () => { try { const docRef = doc(db, "users", auth.currentUser.uid); const docSnap = await getDoc(docRef); let tempBalance; if (docSnap.exists()) { const { notFirstRun, WalletBalance } = docSnap.data(); if (notFirstRun) { tempBalance = WalletBalance; } else { tempBalance = 1000000; await setDoc( docRef, { WalletBalance: tempBalance, notFirstRun: true }, { merge: true } ); } } else { // 用户文档不存在时初始化余额 tempBalance = 1000000; await setDoc(docRef, { WalletBalance: tempBalance, notFirstRun: true }); } setDisplayBalance(tempBalance); } catch (error) { alert(error.message); } }; useEffect(() => { // 组件挂载时执行异步余额查询 checkBalance(); }, []); // 加载状态显示占位符 if (displayBalance === null) { return <View><Text>加载中...</Text></View>; } return ( <View style={{ backgroundColor: "white", alignItems: "center" }}> <Text style={{ fontSize: 42, marginVertical: 30 }}> K{(displayBalance / 100)} </Text> </View> ); };
关键修复点
- 用
useState定义displayBalance状态存储余额数值 - 用
useEffect在组件挂载时触发异步操作 - 异步操作完成后调用
setDisplayBalance更新状态,触发组件重新渲染 - 修复非首次运行时
tempBalance未赋值的问题 - 改用try/catch统一捕获错误,优化错误处理逻辑
- 添加加载状态提示,避免初始渲染显示异常
内容的提问来源于stack exchange,提问作者Mak12
相关产品推荐
相关产品推荐

