React-leaflet自定义组件-上下文未传递?

问题描述 投票:2回答:2

我正在为react-leaflet编写一个自定义组件。这是一个可编辑的弹出窗口,具有其他一些功能。以Here is a codesandbox为例。该组件的源代码为here。本示例仅执行import EditablePopup from 'my-react-leaflet-popup-plugin',这是我项目中的.js文件。效果很好。

我正在尝试使用webpack将其打包为一个节点模块,以便其他人可以使用它。它编译没有问题。您可以看到我的webpack.config.js here。然后,我使用npm link将此模块链接到本地​​计算机上的测试项目。这样做时,我收到错误消息:

TypeError: Cannot read property 'leafletElement' of null

  460 |   value: function value() {
  461 |     var e = this;
  462 |     this.props.open && setTimeout(function () {
> 463 |       e.thePopup.leafletElement._source.openPopup();
      | ^  464 |     }, .001);
  465 |   }
  466 | }, {

即使我摆脱了该条款,我也得到了:

TypeError: Cannot read property 'openPopup' of undefined


  9226 | // @method openOn(map: Map): this
  9227 | // Adds the popup to the map and closes the previous one. The same as `map.openPopup(popup)`.
  9228 | openOn: function openOn(map) {
> 9229 |   map.openPopup(this);
       | ^  9230 |   return this;
  9231 | },
  9232 | onAdd: function onAdd(map) {

就像弹出窗口试图将自身添加到地图中一样,但是没有找到父Map组件的地图实例。我的直觉是,由于某种原因,当使用webpack构建它并将其作为npm模块导入时,react-leaflet映射的上下文未正确传递给我的组件。我不太了解,因为我的组件只是react-leaflet的<Popup>组件的修饰版本。我的<EditablePopup>使用<Popup>作为直接子代,该子代本来应该接收LeafletConsumer上下文使用者包装器。

我不确定为什么在我的项目中链接此组件时,该组件会很好用,但是在通过webpack构建并通过npm导入时会出现此错误。

reactjs webpack custom-component react-leaflet
2个回答
0
投票

我发布的答案受this anwer中的Cannot read property 'Component' of undefined - webpack build of react component plugin启发。我的问题似乎至少与问题React Context API not working from custom NPM component library 相关,并且那些人仍在寻找答案-也许这会有所帮助。

为了解决此问题,我必须对webpack.config.jspackage.json进行调整。


webpack.config.js

更改此:

  libraryTarget: 'commonjs2'

至此:


      library: "EditablePopup",
      libraryTarget: 'umd'

以及将mode: development添加到module.exports


package.json

将我的一些dependencies移到peerDependencies


    // Change from this:
      "dependencies": {
        "html-react-parser": "^0.10.0",
        "leaflet": "^1.6.0",
        "react": "^16.12.0",
        "react-contenteditable": "^3.3.3",
        "react-dom": "^16.12.0",
        "react-leaflet": "^2.6.1",
        "webpack": "^4.41.5"
      },
      "peerDependencies": {
        "react": "^16.12.0",
        "react-dom": "^16.12.0",
        "react-leaflet": "^2.6.1",
        "leaflet": "^1.6.0"
      }

    // to this:
      "dependencies": {
        "html-react-parser": "^0.10.0",
        "react-contenteditable": "^3.3.3",
        "webpack": "^4.41.5"
      },
      "peerDependencies": {
        "react": "^16.12.0",
        "react-dom": "^16.12.0",
        "react-leaflet": "^2.6.1",
        "leaflet": "^1.6.0"
      }


我很确定它的webpack.config.js更改是起因。为了完整起见,以下是对该文件的更改:

// webpack.config.jsvar path = require('path');module.exports = {条目:“ ./ src / EditablePopup.js”,输出:{路径:path.resolve(__ dirname,'build'),文件名:“ EditablePopup.js”,-libraryTarget:'commonjs2',+库:“ EditablePopup”,+ libraryTarget:'umd'},+模式:“开发”,模块:{规则:[{测试:/ \。js $ /,包括:path.resolve(__ dirname,'src'),排除:/(node_modules | bower_components | build)/,采用: [{加载程序:“ babel-loader”,选项:{预设:['@ babel / preset-env']}}]},{测试:/\.css$/,采用: [{loader:'style-loader'},{loader:'css-loader'}]}]},外部因素:{'react-dom':'commonjs react-dom',传单:{commonjs:'传单',commonjs2:'传单',根:“ L”},“反应传单”:{commonjs:'反应叶',commonjs2:'反应叶',root:“ ReactLeaflet”},反应:{commonjs:'反应',commonjs2:'反应',root:“反应”}}};

0
投票

我在工作场所遇到类似的问题,现在我怀疑我们宣布Webpack配置的(类似)方法是罪魁祸首。但是对我来说,仅更改libraryTarget并没有任何效果。在描述我们的设置后,我的见解如下...

我们有一个视觉组件集合,我们正在捆绑到一个“库”中,该库将被导入到一个主要项目中。主项目需要获取一些外部数据,但需要在整个库组件的任意位置使用。而且我们不想到处传递道具。那么背景吧?除非提供者(我们在“主”项目中设置和初始化)和使用者位于库边界的不同侧面,否则使用者的上下文始终是未定义的(或者,无论“ createContext”的默认设置如何) ...我们没有使用初始化程序。

无论如何,快向前走一堆。如果我从将库中的每个不同组件都列为自己独立的“入口”(在webpack文件中)改为改为构建一个index.js文件,该文件可以导入并重新导出所有内容,并且仅以单数形式包含该文件“进入”(在webpack中)-然后事情开始起作用。

因为React上下文API需要创建要共享的Context对象,但是共享的概念(无论如何,我想还是在模块级别)。它不能是truly全局的。因此,不同的入口点,不同的模块,不同的上下文对象。消费者被冷落。

© www.soinside.com 2019 - 2024. All rights reserved.