ReactJS按钮导航无法传递Item组件经纬度参数问题排查
我有一个Item组件,从API获取物品的latitude(纬度)和longitude(经度),组件内设有按钮,点击后导航至Map组件,需要在地图上标记并放大该物品的位置。我在Item组件中用navigate尝试传递lat和lng作为参数,代码如下:
const itemLat = item.latitude; const itemLng = item.longitude; const navigateToItem = ({ itemLat, itemLng }) => { navigate(`/map/?lat=${itemLat}&lng=${itemLng}`); }); console.log(itemLat, itemLng); };
按钮代码:
<Button onClick={navigateToItem}> Show on map </Button>
目前问题:itemLat和itemLng打印结果为undefined,地图能打开,但显示所有标记点,未过滤出目标物品。Map组件代码如下:
function Map() { const { id } = useParams(); const [lat, setLat] = useState(0); const [lng, setLng] = useState(0); const [allData, setAllData] = useState([]); const [filteredData, setFilteredData] = useState([]); const [item, setItem] = useState(null); const mapRef = useRef(null); // Fetching all items useEffect(() => { fetch("https://URL/api/item-list/") .then((res) => { console.log(res); return res.json(); }) .then((data) => { console.log(data); setAllData(data); setFilteredData(data); }) .catch((e) => { console.log("ERROR", e); }); }, [id]); const handleFilter = (data) => { setFilteredData(data); }; useEffect(() => { if (mapRef.current && filteredData.length > 0) { const bounds = new window.google.maps.LatLngBounds(); filteredData.forEach((value) => { const position = { lat: value.latitude, lng: value.longitude }; bounds.extend(position); }); mapRef.current.fitBounds(bounds); } }, [mapRef, filteredData]); return ( <div> <GoogleMap center={{ mapRef }} onLoad={(map) => { mapRef.current = map; }} > {filteredData.map((value) => { const position = { lat: value.latitude, lng: value.longitude, }; return ( <MarkerF clickable={true} position={position} key={value.id} onClick={() => handleMarkerClick(value)} /> ); })} ...rest of code
请问我哪里出错了?
1. Item组件:函数参数错误导致变量undefined
你定义的navigateToItem函数接收了{ itemLat, itemLng }作为参数,但按钮点击时传递的是事件对象,不是你需要的纬度经度;同时你已经在函数外部定义了itemLat和itemLng,不需要再通过参数接收——参数里的同名变量会覆盖外部变量,导致打印出undefined。
修复代码:
const itemLat = item.latitude; const itemLng = item.longitude; // 去掉多余参数,直接使用外部已定义的变量 const navigateToItem = () => { navigate(`/map/?lat=${itemLat}&lng=${itemLng}`); console.log(itemLat, itemLng); // 现在能正确打印值 };
2. Map组件:未正确获取URL查询参数
你用useParams()获取id,但传递的是URL查询参数(?lat=xxx&lng=xxx),不是路由参数(比如/map/123里的123),所以需要用useSearchParams来获取lat和lng。
修复代码:
首先导入useSearchParams:
import { useSearchParams } from 'react-router-dom';
然后在组件内使用:
function Map() { const [searchParams] = useSearchParams(); // 获取URL中的lat和lng,转为数字类型 const targetLat = parseFloat(searchParams.get('lat')); const targetLng = parseFloat(searchParams.get('lng')); // ...其他代码 }
3. Map组件:未根据传递的坐标过滤数据
获取到目标坐标后,需要在获取数据时或数据更新时,过滤出对应坐标的物品,而不是直接把所有数据赋值给filteredData。
修复代码:
修改获取数据的useEffect:
useEffect(() => { fetch("https://URL/api/item-list/") .then((res) => res.json()) .then((data) => { setAllData(data); // 有目标坐标则过滤匹配物品,否则显示全部 if (!isNaN(targetLat) && !isNaN(targetLng)) { const filtered = data.filter(item => parseFloat(item.latitude) === targetLat && parseFloat(item.longitude) === targetLng ); setFilteredData(filtered); } else { setFilteredData(data); } }) .catch((e) => console.log("ERROR", e)); }, [targetLat, targetLng]); // 依赖改为目标坐标,坐标变化时重新过滤
4. Map组件:GoogleMap的center属性设置错误
你把center设为{{ mapRef }},这是错误的,center需要是包含lat和lng的对象。如果有过滤后的物品,直接用第一个物品的坐标作为中心;否则设默认值。
修复代码:
<GoogleMap center={filteredData.length > 0 ? { lat: filteredData[0].latitude, lng: filteredData[0].longitude } : { lat: 0, lng: 0 } // 默认中心坐标 } onLoad={(map) => { mapRef.current = map; }} >
完成以上修复后,点击按钮就能正确传递坐标,地图会只显示目标物品的标记并自动放大到该位置。
内容的提问来源于stack exchange,提问作者Jo_K

