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

React中遍历数组调用计算函数更新useState?修正NaN数组问题

问题解决:计算距离返回NaN数组的修复

问题背景

我有一组包含经纬度的数据:

data=[{id: 4, lat: -33.85664180722481, long: 151.2153396118792},{..},{...}..];

我用calculateDistance()函数计算地图点击位置(location)与每个数据元素的距离,想把结果存入数组后用useState更新状态,但当前代码返回的是NaN数组。

当前代码

useEffect逻辑

useEffect(() => 
{
  const distance = data.map((hero) => {
    calculateDistance(location?.lat, location?.lng, hero?.lat,hero?.long);
    return distance;
  });
  setDistance(distance);
},[location, data]);

计算距离函数

const [distance, setDistance] = useState(null);
const data = useHeroesData();
//console.log(data);
const calculateDistance = (lat1, lon1, lat2, lon2) => {
  // 通用地理测量函数
  var R = 6378.137; // 地球半径(公里)
  var dLat = (lat2 * Math.PI) / 180 - (lat1 * Math.PI) / 180;
  var dLon = (lon2 * Math.PI) / 180 - (lon1 * Math.PI) / 180;
  var a =
    Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.cos((lat1 * Math.PI) / 180) *
      Math.cos((lat2 * Math.PI) / 180) *
      Math.sin(dLon / 2) *
      Math.sin(dLon / 2);
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  var d = R * c;
  return d; // 返回公里数
};

问题原因

  1. map回调返回错误:在data.map的回调里,调用calculateDistance后没有返回计算结果,反而返回了正在定义的distance变量——此时distance还未完成赋值,导致每次迭代都返回undefined,最终数组全是undefined,后续计算自然得到NaN。
  2. 缺少边界检查:如果location或hero的经纬度不存在(比如location未初始化、data元素缺失坐标),传入undefined到计算函数会触发无效数学运算,返回NaN。

修复方案

修正后的useEffect代码

useEffect(() => {
  // 先校验location是否有有效经纬度,避免无效计算
  if (!location?.lat || !location?.lng) {
    setDistance([]);
    return;
  }

  const distanceArr = data.map((hero) => {
    // 校验当前hero的经纬度是否有效
    if (!hero?.lat || !hero?.long) {
      return null; // 可根据需求返回0、'无效坐标'等替代值
    }
    // 返回calculateDistance的计算结果
    return calculateDistance(location.lat, location.lng, hero.lat, hero.long);
  });
  setDistance(distanceArr);
}, [location, data]);

额外优化:给计算函数加参数校验

在calculateDistance里提前校验参数有效性,进一步提升代码健壮性:

const calculateDistance = (lat1, lon1, lat2, lon2) => {
  // 校验参数是否为有效数字
  if (typeof lat1 !== 'number' || typeof lon1 !== 'number' || typeof lat2 !== 'number' || typeof lon2 !== 'number') {
    return null; // 或0、NaN,根据业务需求调整
  }

  var R = 6378.137; // 地球半径(公里)
  var dLat = (lat2 * Math.PI) / 180 - (lat1 * Math.PI) / 180;
  var dLon = (lon2 * Math.PI) / 180 - (lon1 * Math.PI) / 180;
  var a =
    Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.cos((lat1 * Math.PI) / 180) *
      Math.cos((lat2 * Math.PI) / 180) *
      Math.sin(dLon / 2) *
      Math.sin(dLon / 2);
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  var d = R * c;
  return d; // 返回公里数
};

说明

  • 修正map的返回逻辑,确保每个迭代返回实际计算的距离值;
  • 增加多层边界检查,避免传入无效坐标参数;
  • 可选的函数参数校验,让代码在异常场景下更可控。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 08:00:54