Mapbox自定义GeoJSON数据不显示,报读取length未定义错误
问题分析与修复方案
核心错误点
- GeoJSON结构不规范:传给Mapbox的
data格式错误,Mapbox要求GeoJSON必须是FeatureCollection类型,需包含type: "FeatureCollection"和features属性,你直接传{ points }不符合规范,这是触发length读取错误的主要原因。 - 坐标类型错误:
toFixed(4)会将数字转为字符串,而Mapbox的coordinates需要数字类型的经纬度值,字符串会导致解析失败。 - 冗余的Promise.all:
alleArtikel?.map()返回普通对象数组,不是Promise数组,用Promise.all包裹完全多余,易引发异步逻辑混乱。 - 未处理初始状态:
points初始值可能为undefined,直接访问points.length会报错,需添加可选链判断。 - 依赖缺失:
getData中用到alleArtikel但依赖数组为空,组件更新时无法获取最新数据。
修复后的代码
const getData = useCallback(async () => { if (!alleArtikel) return; // 直接生成Feature数组,去掉多余的Promise.all const features = alleArtikel.map((artikel) => ({ type: "Feature", properties: { userId: artikel.userId, userBild: artikel.userBild, artikelId: artikel._id, anzahl: alleArtikel.length, }, geometry: { type: "Point", coordinates: [ // 转成数字类型,保留四位小数需用Number包裹toFixed结果 Number(parseFloat(artikel.long).toFixed(4)), Number(parseFloat(artikel.lat).toFixed(4)), ], }, })); setPoints(features); }, [alleArtikel]); // 添加alleArtikel到依赖数组 useEffect(() => { // 用可选链处理points初始为undefined的情况,同时确保map实例存在 if (points?.length && map) { // 用once避免重复绑定load事件 if (map.loaded()) { addMapSource(); } else { map.once("load", addMapSource); } } function addMapSource() { // 构建标准的FeatureCollection格式 map.addSource("users", { type: "geojson", data: { type: "FeatureCollection", features: points, }, cluster: true, clusterMaxZoom: 14, clusterRadius: 50, }); // ...后续图层添加逻辑 } }, [points, map]);
额外注意
- 使用
map.once("load")替代map.on("load"),防止组件更新时重复绑定事件导致多次添加数据源报错。 - 确保
map实例加入useEffect依赖,避免闭包问题访问旧实例。
内容的提问来源于stack exchange,提问作者Captai-N
相关产品推荐
相关产品推荐

