You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

问题描述

显示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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 12:05:44