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

React Native中JSX渲染Promise返回值问题求助

问题解决:异步计算的距离无法在JSX中正常渲染

问题根源

你用useMemo包裹的异步函数会返回一个Promise对象,而非实际的距离数值,所以直接在JSX中渲染distance时,显示的是Promise实例而非预期结果。

解决方案

方案1:封装独立子组件(推荐)

因为ci_empAddressDetails来自循环,直接在循环内使用useState会导致状态混乱,把距离计算逻辑封装成独立子组件,每个子组件单独管理自身状态即可解决:

// 新建 DistanceDisplay.jsx
import React, { useState, useEffect } from 'react';
import haversine from 'haversine';
import { getCurrentLocation } from 'src/utils/helpers';
import { View, Text } from 'react-native';

const DistanceDisplay = ({ addressDetails, styles }) => {
  const [distance, setDistance] = useState(null);
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    const calculateDistance = async () => {
      setIsLoading(true);
      if (!isEmpty(addressDetails)) {
        try {
          const { value } = addressDetails[0];
          const { ci_latitude, ci_longitude } = value[0];
          const res = await getCurrentLocation();
          const end = { latitude: ci_latitude, longitude: ci_longitude };
          const result = haversine(res, end, { unit: 'mile' });
          setDistance(result);
        } catch (err) {
          console.error('计算距离失败:', err);
          setDistance(false);
        }
      } else {
        setDistance(false);
      }
      setIsLoading(false);
    };

    calculateDistance();
  }, [addressDetails]);

  return (
    <View style={{ width: '30%', justifyContent: 'flex-end', alignItems: 'flex-end' }}>
      <Text style={[styles.linkTo, styles.labelName]}>
        {isEmpty(addressDetails) 
          ? '-' 
          : isLoading 
            ? '加载中...' 
            : distance !== null 
              ? distance.toFixed(2) // 可按需格式化数值
              : '-'}
      </Text>
    </View>
  );
};

export default DistanceDisplay;

在循环中使用该组件:

{/* 假设你的循环逻辑如下 */}
{yourDataList.map(item => (
  <DistanceDisplay 
    key={item.c_id} 
    addressDetails={item.cusInfo[0].ci_empAddressDetails} 
    styles={styles} 
  />
))}

方案2:useEffect + useRef + 强制更新(不拆分组件时适用)

如果不想拆分组件,可通过useRef存储计算结果,配合useEffect执行异步逻辑,再用空状态触发重渲染:

import { useRef, useEffect, useState } from 'react';
// ... 其他导入代码

// 原组件内添加
const distanceRef = useRef(null);
const isLoadingRef = useRef(false);
const [, forceUpdate] = useState(); // 用于强制触发重渲染

useEffect(() => {
  const calculateDistance = async () => {
    isLoadingRef.current = true;
    forceUpdate(); // 触发重渲染显示加载状态

    if (!isEmpty(ci_empAddressDetails)) {
      try {
        const { value } = ci_empAddressDetails[0];
        const { ci_latitude, ci_longitude } = value[0];
        const res = await getCurrentLocation();
        const end = { latitude: ci_latitude, longitude: ci_longitude };
        const result = haversine(res, end, { unit: 'mile' });
        distanceRef.current = result;
      } catch (err) {
        console.error('计算距离失败:', err);
        distanceRef.current = false;
      }
    } else {
      distanceRef.current = false;
    }

    isLoadingRef.current = false;
    forceUpdate(); // 计算完成后触发重渲染更新显示
  };

  calculateDistance();
}, [ci_empAddressDetails]);

// JSX渲染部分修改为
<View style={{ width: '30%', justifyContent: 'flex-end', alignItems: 'flex-end' }}>
  <Text style={[styles.linkTo, styles.labelName]}>
    {isEmpty(ci_empAddressDetails) 
      ? '-' 
      : isLoadingRef.current 
        ? '加载中...' 
        : distanceRef.current !== null 
          ? distanceRef.current.toFixed(2) 
          : '-'}
  </Text>
</View>

关键说明

  • 异步函数本身返回Promise,因此无法通过useMemo直接获取同步计算结果
  • 封装子组件是更符合React组件设计的方式,能彻底避免循环内状态管理的冲突
  • 添加加载状态可提升用户体验,避免页面显示空白或异常内容

内容的提问来源于stack exchange,提问作者achu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 16:40:41