React эквивалент document.createElement ()

В настоящее время я использую Mapbox в приложении React. Чтобы создать собственный маркер, вам нужно сделать что-то вроде этого:

var el = document.createElement('div');
el.className = 'marker';

new mapboxgl.Marker(el)
.setLngLat(marker.geometry.coordinates)
.addTo(map);

Это был React, и я попробовал сделать:

new mapboxgl.Marker(<div className='marker' />)
.setLngLat(marker.geometry.coordinates)
.addTo(map);

Но это не работает ... В приведенном выше контексте, что было бы эквивалентом document.createElement()? Когда я использую document.createElement(), он работает, но я чувствую, что это не «правильный» способ делать что-то. Я также хотел бы абстрагировать маркер в его собственный компонент ...

Что будет, если попробовать mapboxgl.Marker(React.createElement('div', { className: 'marker' }, ''));

Dan 17.05.2018 12:50

@Dan Это не сработает, потому что React.createElement создает ReactElement, который является простым объектом, а не элементом DOM.

Yury Tarabanko 17.05.2018 12:53

Было бы удобно, если бы была функция, которая могла бы взять объект, который создает React.createElement, и преобразовать его в элемент DOM ...

user818700 17.05.2018 13:23

Привет, ты нашел, как это сделать в React. Или вы продолжили document.createElement.?

Johnson 31.05.2018 09:36
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
5
4
15 726
3

Ответы 3

Вы можете попробовать обертку React для Mapbox: react-mapbox-gl

<Marker coordinates = {coordinates} className = {className}>

Если вы хотите использовать ванильный Mapbox, вы можете посмотреть их пример приложения с всплывающей подсказкой, используя React: github.com/mapbox/mapbox-react-examples/tree/master/….

jumoel 17.05.2018 12:54

@jumoel Я использовал эти примеры, чтобы конкретизировать свой ответ, спасибо!

DogPawHat 17.05.2018 13:27

Часть секретного соуса React заключается в том, что вы не взаимодействуете с реальной DOM, если можете помочь, вы делаете обновление виртуальной DOM, если состояние или свойства изменяются, и позволяете React обрабатывать рендеринг.

Если вам действительно нужно выполнять более традиционные манипуляции с DOM, вы должны использовать refs (https://reactjs.org/docs/refs-and-the-dom.html), чтобы обрабатывать его изолированным способом. Обычно он используется экономно, но кажется идеальным для использования с Mapbox.

Мой очень наивный пример:

// Very simplified
class MapboxWrapper extends React.Component {
  constructor(props) {
    super(props);
    this.markerRef = React.createRef();
  }

  createMarker() {
    new mapboxgl.Marker(this.markerRef)
      .setLngLat(marker.geometry.coordinates)
      .addTo(map);
  }

  componentDidMount() {
    this.createMarker();
  }

  render() {
    return (
      // ...Wrapper elements that you might need
      <div ref = {this.markerRef} className = "marker" />
    )  
  }
}

Любезно предоставлено @jumoel, я бы рекомендовал прочитать примеры https://github.com/mapbox/mapbox-react-examples/tree/master/react-tooltip и https://github.com/mapbox/mapbox-react-examples/ в целом, поскольку они более конкретизированы, чем этот пример.

У меня была такая же проблема, и я нашел два решения:

Решение 1

1. Импортировать библиотеку ReactDOM:

import ReactDOM from 'react-dom';

2. Создайте пустой div, как предлагает официальный учебник Mapbox:

const el = document.createElement("div");
el.className = "marker";

3. Визуализируйте компонент React вашего маркера во вновь созданный элемент el:

ReactDOM.render(<div className='marker' />, el);

4. Добавьте это на свою карту

new mapboxgl.Marker(el)
  .setLngLat(marker.geometry.coordinates)
  .addTo(map);

Решение 2

1. Импортировать библиотеку ReactDOMServer:

import ReactDOMServer from 'react-dom/server';

2. Создайте пустой div, как предлагает официальный учебник Mapbox:

const el = document.createElement("div");
el.className = "marker";

3. Создайте статическую разметку HTML из компонента React вашего маркера и назначьте его el.innerHTML

el.innerHTML = ReactDOMServer.renderToStaticMarkup(<div className='marker' />);

4. Добавьте это на свою карту

new mapboxgl.Marker(el)
  .setLngLat(marker.geometry.coordinates)
  .addTo(map);

Примечание Решение 2 имеет один недостаток. Элемент-маркер теряет свою интерактивность и методы жизненного цикла (в основном все преимущества, которые мы можем получить от React), поскольку он становится простой разметкой HTML.

Другие вопросы по теме