Next JS 13集成Mapbox GL报错:Cannot read properties of undefined (reading 'mark')
Next.js 13集成Mapbox GL报错排查与解决
问题描述
我按照Mapbox官方指南在Next.js 13中集成Mapbox GL,编写了基础实现代码,但运行时出现错误:Cannot read properties of undefined (reading 'mark'),错误位置在创建mapboxgl.Map实例的代码行。此前尝试使用react-map-gl时还遇到过静默失败的问题。
报错代码
"use client" import React, {useEffect, useRef} from "react"; import "mapbox-gl/dist/mapbox-gl.css"; import mapboxgl from "mapbox-gl"; mapboxgl.accessToken = process.env.NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN; export const MapGL = ({}) => { // create the map and configure it // check out the API reference for more options // https://docs.mapbox.com/mapbox-gl-js/api/map/ const mapA = new mapboxgl.Map({ container: "mapA", style: "mapbox://styles/mapbox/dark-v11", center: [74.854672, 34.061143], zoom: 14, pitch: 80, }); return <div id="mapA" style={{width: "100%", height: "100vh"}} />; };
解决方案
核心问题:直接在组件函数体中创建Map实例时,目标DOM容器还未渲染挂载,Mapbox无法找到有效容器导致初始化失败。
修改步骤
- 用
useRef获取容器DOM节点,避免依赖ID选择器的潜在问题 - 借助
useEffect钩子在组件挂载完成(DOM渲染后)再初始化地图 - 添加组件卸载时的地图销毁逻辑,防止内存泄漏
- 用
修改后的代码:
"use client" import React, { useEffect, useRef } from "react"; import "mapbox-gl/dist/mapbox-gl.css"; import mapboxgl from "mapbox-gl"; mapboxgl.accessToken = process.env.NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN; export const MapGL = () => { const mapContainerRef = useRef(null); const mapRef = useRef(null); useEffect(() => { // 容器未挂载或地图已初始化则跳过 if (!mapContainerRef.current || mapRef.current) return; // 初始化地图实例 mapRef.current = new mapboxgl.Map({ container: mapContainerRef.current, style: "mapbox://styles/mapbox/dark-v11", center: [74.854672, 34.061143], zoom: 14, pitch: 80, }); // 组件卸载时清理地图实例 return () => { if (mapRef.current) { mapRef.current.remove(); mapRef.current = null; } }; }, []); return <div ref={mapContainerRef} style={{ width: "100%", height: "100vh" }} />; };
- 额外注意事项
- 确保
NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN环境变量已正确配置在.env.local文件中,变量名必须以NEXT_PUBLIC_开头才能在客户端组件中访问 - 若使用react-map-gl,需确保版本与Next.js 13兼容,同样要在
useEffect中完成初始化,避免DOM未挂载的问题
- 确保
内容的提问来源于stack exchange,提问作者ebra13
相关产品推荐
相关产品推荐

