Пользовательский компонент React-leaflet - контекст не передается? - PullRequest
2 голосов
/ 08 января 2020

Я пишу пользовательский компонент для реагирования-листовки. Это редактируемое всплывающее окно с несколькими другими функциями. Вот примеры кодов и для примера. Исходный код компонента здесь . Этот пример просто делает import EditablePopup from 'my-react-leaflet-popup-plugin', который является. js файлом в моем проекте. Работает хорошо.

Я пытаюсь связать это с помощью веб-пакета, чтобы упаковать его как модуль узла, чтобы другие могли его использовать. Компилируется без проблем. Вы можете увидеть мой webpack.config. js здесь . Затем я использую 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) {

Это как всплывающее окно пытается добавить сам на карту, но не находит экземпляр карты родительского компонента карты. Я догадываюсь, что по какой-то причине при сборке с использованием веб-пакета и импорте его в виде модуля npm контекст карты реагирования-листовки не передается должным образом моему компоненту. Что я на самом деле не понимаю, так как мой компонент - это просто одетая версия компонента <Popup> Reaction-leaflet. Мой <EditablePopup> использует <Popup> в качестве прямого потомка, который по своей природе должен получать оболочку потребителя контекста LeafletConsumer.

Я не уверен, почему этот компонент прекрасно работает, когда он связан в моем проекте, но имеет эту ошибку при сборке через веб-пакет и импорте через npm.

Ответы [ 3 ]

1 голос
/ 12 марта 2020

У меня похожая проблема на рабочем месте, и теперь я подозреваю, что виновным является (похожий) способ, которым мы объявляем конфигурацию webpack. Но для меня просто изменение libraryTarget не имело никакого эффекта. Мои идеи ниже после описания нашей установки ...

У нас есть коллекция визуальных компонентов, которые мы объединяем в «библиотеку», которую мы импортируем в основной проект. Существуют некоторые внешние данные, которые необходимо извлечь из основного проекта, но которые необходимо использовать в произвольных местах по всем компонентам библиотеки. И мы не хотели распространять реквизит везде. Так что контекст, верно? За исключением случаев, когда поставщик (который мы устанавливаем и инициализируем в «основном» проекте) и потребитель находились по разные стороны границы библиотеки, контекст для потребителя всегда был неопределенным (или, скорее, каким бы ни было значение по умолчанию для «createContext») ... мы не использовали инициализатор).

Во всяком случае, перемотка вперед. Если я перейду от перечисления каждого отдельного компонента в библиотеке в качестве своей собственной независимой «записи» (в файле webpack) к созданию вместо этого одного файла index. js, который импортирует и реэкспортирует все - и включит только этот один файл как единственная «запись» (в веб-пакете) - тогда все заработало.

Поскольку для API контекста React требуется, чтобы созданный объект Context был предоставлен в общий доступ, но понятие совместного использования (я думаю, в любом случае) в модуле уровень. Он не должен быть истинно глобальным. Так разные точки входа, разные модули, разные объекты контекста. Потребитель остался на холоде.

0 голосов
/ 10 апреля 2020

Возможно, вам нужно обернуть пользовательский компонент в withLeaflet? Я обнаружил, что этот SO-ответ очень ясен на этапах создания пользовательских компонентов с react-leaflet.

. Использование HO C сделает карту (и остальную часть контекста). ) доступно в вашей реализации createLeafletElement после монтирования карты.

0 голосов
/ 11 марта 2020

Я публикую ответ, вдохновленный этим ответом в Невозможно прочитать свойство 'Компонент' из неопределенного - сборка веб-пакета плагина реагирующего компонента . Мой вопрос здесь, по крайней мере, в некоторой степени связан с вопросом React Context API не работает из пользовательской NPM библиотеки компонентов , и эти люди все еще ищут ответ - возможно, это поможет.

Мне пришлось внести коррективы в мой webpack.config.js, а также package.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 изменения, которые были кикером. Для полноты вот изменения этого файла:


    <b>// webpack.config.js</b>

    var path = require('path');
    module.exports = {
        entry: './src/EditablePopup.js',
        output: {
            path: path.resolve(__dirname, 'build'),
            filename: 'EditablePopup.js',
    <b>-       <del>libraryTarget: 'commonjs2',</del>
    +       library: "EditablePopup",
    +       libraryTarget: 'umd'</b>
        },
    <b>+   mode: "development",</b>
        module: {
            rules: [
                {
                    test: /\.js$/,
                    include: path.resolve(__dirname, 'src'),
                    exclude: /(node_modules|bower_components|build)/,
                    use: [
                        {
                            loader: 'babel-loader',
                            options: {
                                presets: ['@babel/preset-env']
                            }
                        }
                    ]
                },
                { 
                    test : /\.css$/, 
                    use: [
                        { loader: 'style-loader' },
                        { loader: 'css-loader' }
                    ]  
                }
            ]
        },
        externals: {
            'react-dom': 'commonjs react-dom',
            leaflet: {
                commonjs: 'leaflet',
                commonjs2: 'leaflet',
                root: 'L'
            },
            'react-leaflet': {
                commonjs: 'react-leaflet',
                commonjs2: 'react-leaflet',
                root: 'ReactLeaflet'
            },
            react: {
                commonjs: 'react',
                commonjs2: 'react',
                root: 'React'
            }
        }
    };

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...