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

ReactJS按由近到远获取5个邻近位置返回重复结果问题

问题根源

两个核心bug导致返回重复结果:

  • findNearestLocation 返回值取值错误:map-nearest-location 包的查找结果不是直接返回位置对象,返回结构为 { location: 原始位置数据, distance: 距离值, units: 距离单位 }。原代码直接从返回结果上取lat、lng属性,拿到的永远是undefined,后续过滤已选位置的逻辑完全失效,每次循环查找都会命中同一个最近点。
  • 位置过滤逻辑运算符错误:原过滤条件 location.lat !== nearest.lat && location.lng !== nearest.lng 逻辑完全颠倒,会误删大量和已选点同经度/同纬度的有效点位,正确逻辑应该是仅排除经纬度和已选点完全一致的点位。
  • 额外非核心问题:useEffect 直接传入 async 回调不符合React设计规范,useEffect 期望返回清理函数,async函数返回Promise会导致清理逻辑无法正常执行;原代码误用map方法做数组遍历填充,属于API使用不规范。
修复后完整代码
const [myLocation, setMylocation] = useState(null);
const [status, setStatus] = useState(null);
const [dapat, setDapat] = useState([]);

useEffect(() => {
  getLocation();
}, []);

useEffect(() => {
  // 不要直接给useEffect传async回调,内部定义异步函数调用
  const fetchNearestLocations = async () => {
    const response = await axios.get(Urlfromdatabase);
    // 直接用map生成目标数组,不需要额外push
    let locations = response.data.map((user) => ({
      "name": user.name,
      "address": user.address,
      "phone": user.phone.toString(),
      "facility": user.facility,
      "lat": Number(user.lat),
      "lng": Number(user.lng)
    }));

    if (!myLocation || locations.length === 0) return;

    const nearestLocations = [];
    for (let step = 0; step < 5; step++) {
      if (locations.length === 0) break;
      const nearestRes = findNearestLocation(myLocation, locations);
      // 从返回结果中取实际的位置对象
      const nearestPoint = nearestRes.location;
      nearestLocations.push(nearestPoint);
      // 修正过滤逻辑:仅排除经纬度完全匹配的已选点
      locations = locations.filter(location => {
        return !(location.lat === nearestPoint.lat && location.lng === nearestPoint.lng);
      });
    }
    setDapat(nearestLocations);
    console.log(nearestLocations);
  }

  fetchNearestLocations();
}, [myLocation]);

const getLocation = () => {
  if (!navigator.geolocation) {
    setStatus('geolocation not support on your browser!!');
  } else {
    setStatus('locating...!!');
    navigator.geolocation.getCurrentPosition((position) => {
      setStatus(null);
      setMylocation({
        lat: position.coords.latitude,
        lng: position.coords.longitude
      })
    }, () => {
      // 修正单引号转义问题
      setStatus("can't get the location!");
    });
  }
}
验证说明

修复后每次循环找到最近点后,都会正确把该点从待选列表中移除,下一轮查找会在剩余点位中找次近的点,最终得到按距离由近到远排序的5个不同点位。如果你的点位数据里存在经纬度完全一致的重复数据,还可以给每个点位加唯一id,过滤时通过id判断,避免经纬度重复导致的误过滤。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 22:48:22