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
相关产品推荐
相关产品推荐

