开发react-leaflet第三方插件时遇No Context Provided错误求助
解决React-Leaflet自定义组件库中
useLeafletContext()上下文缺失问题 问题描述
开发React-Leaflet自定义插件组件时,遇到以下错误:
No context provided: useLeafletContext() can only be used in a descendant of <MapContainer>
使用Vite React模板构建组件库及引用该库的Demo应用,复现步骤:
- 在
my-component-library/目录执行npm i和npm run build,再在demo-app/目录执行npm i和npm run dev,地图可正常显示; - 取消
app.tsx中<Ellipse>组件的注释,刷新页面后控制台出现上述错误。
更新补充:错误仅在使用相对路径导入(如npm i ../my-component-library)且处于生产模式时出现,开发模式和从.tgz文件安装则运行正常。Demo内定义相同<Ellipse>组件可正常运行,推测问题源于组件库打包方式导致的多实例冲突。
原因分析
通过相对路径安装组件库时,生产模式下组件库和Demo应用可能各自打包了react-leaflet及@react-leaflet/core的独立实例,导致MapContainer提供的上下文无法在跨实例的组件间共享,最终触发useLeafletContext()找不到上下文的错误。
解决方案
1. 配置组件库外部化依赖
修改组件库的vite.config.ts,将React-Leaflet相关依赖标记为外部依赖,避免打包进组件库代码:
// my-component-library/vite.config.ts import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; export default defineConfig({ plugins: [react()], build: { lib: { entry: 'src/index.ts', name: 'MyReactLeafletComponents', formats: ['es', 'umd'], fileName: (format) => `my-react-leaflet-components.${format}.js`, }, rollupOptions: { // 外部化依赖,让宿主应用提供这些包 external: ['react', 'react-dom', 'leaflet', 'react-leaflet', '@react-leaflet/core'], output: { // 全局变量映射,用于UMD格式 globals: { react: 'React', 'react-dom': 'ReactDOM', leaflet: 'L', 'react-leaflet': 'ReactLeaflet', '@react-leaflet/core': 'ReactLeafletCore', }, }, }, }, });
同时在组件库的package.json中添加peerDependencies,明确声明依赖版本要求:
"peerDependencies": { "react": "^18.0.0", "react-dom": "^18.0.0", "leaflet": "^1.9.0", "react-leaflet": "^4.2.0", "@react-leaflet/core": "^2.1.0" }
2. 统一Demo应用的依赖实例
- 推荐方式:组件库打包后生成tgz文件,Demo应用通过该文件安装:
# 在组件库目录执行打包 npm run build # 在Demo应用目录安装tgz包 npm install ../my-component-library/dist/my-react-leaflet-components.tgz - 备选方案:在Demo应用的
vite.config.ts中添加别名,强制指向同一依赖实例:// demo-app/vite.config.ts import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import path from 'path'; export default defineConfig({ plugins: [react()], resolve: { alias: { 'react-leaflet': path.resolve(__dirname, './node_modules/react-leaflet'), '@react-leaflet/core': path.resolve(__dirname, './node_modules/@react-leaflet/core'), 'leaflet': path.resolve(__dirname, './node_modules/leaflet'), }, }, });
3. 验证生产模式
在Demo应用中执行生产构建并预览,确认错误消失:
npm run build npm run preview
内容的提问来源于stack exchange,提问作者tgordon18
相关产品推荐
相关产品推荐

