Автор Сэмюэл Лисснер

В billy mobile мы обновили интерфейс с помощью react.js и redux. Одно совершенно новое приложение требует большого количества графиков. Изначально мы добились определенных успехов с Chart.js. Относительно скоро мы обнаружили присущие ему ограничения, используя ‹canvas› для рендеринга элементов в браузере, особенно для всплывающих подсказок, которые переполняют родительский контейнер холста. Мы решили перенести наши графики на d3.js, хотя столкнулись с проблемой плавной интеграции библиотеки с нашей существующей архитектурой реакции. Как команда фронтенд Билли, мы хотели бы поделиться своим опытом со всеми, кто стремится объединить две библиотеки.

Резюме

В этой памятке кратко описаны различные парадигмы интеграции d3.js с react.js. Нет четкого единого устоявшегося пути решения проблемы интеграции. Первый интуитивно понятный, но ошибочный подход - использовать обе библиотеки путем параллельного рендеринга DOM. Однако это привело к столкновениям между response и d3, управляющим этой частью изменяемой DOM. С другой стороны, лучшие практики:

  1. React для рендеринга DOM, d3 для математики;
  2. Используйте библиотеку react-faux-dom для интеграции существующего кода d3;
  3. Не отображайте DOM, используйте холст.

Хорошим способом выглядит парадигма 1. В статье Элайджа Микса используется исключительно реакция на рендеринг элементов DOM, чтобы избежать конфликтов элементов управления React / d3 - d3 для математики. Тем не менее, многие авторы, похоже, выбирают парадигму 2 (ложная доминанта). Он останется нетронутым, будет иметь полный контроль над (виртуальным) DOM, позволяя при этом полностью использовать d3. Это можно рассматривать как вариант, когда необходимо интегрировать уже существующий, полностью реализованный код d3.

Интеграции

Базовые руководства

Оригинальный подход (проблематичный): параллельное использование обеих библиотек для рендеринга DOM

Визуализируйте элемент контейнера d3 с помощью response, а затем позвольте d3 выполнять остальные манипуляции с DOM самостоятельно. Тем самым вы выходите из дерева реакций. Но это оставляет вас с изменяемым DOM, управляемым d3. Это может вызвать реакцию на выход из элементов DOM, поскольку он берет на себя полный контроль над DOM-виртуальными деревьями DOM. См. Раздел согласование в React docs.

Примечание. Вы не можете легко визуализировать реагирующие компоненты с помощью функций d3. selection.html (‹MyComponent /›) не работает.

Учитывая эти фундаментальные проблемы, на практике использовались различные парадигмы, чтобы избежать ситуации конфликтующего управления DOM.

Парадигма 1: Реагируйте на модель DOM, d3 на математику

Компилирует элементы DOM как реагирующие компоненты, но с помощью d3 (математических) функций. Не использует привязки и выбор данных d3.

Парадигма 2: Используйте Faux DOM для изолированной визуализации d3

Та же основная проблема, что и в парадигме 2: нельзя использовать d3 для обновления DOM, вместо этого используйте реакцию. Библиотека faux-dom позволяет создать поддельный DOM, манипулировать им с помощью D3, а затем преобразовать его в компонент React. React не будет напрямую управлять этой DOM.

Парадигма 3: Используйте холст вместо отрисовки DOM

Примеры кода

Прежде чем просматривать примеры кода, лучше не забудьте прочитать хотя бы главы выше, посвященные ошибочному, оригинальному подходу и парадигме 1.

Проблемный, оригинальный подход

В следующем примере вы можете ясно видеть, что жизненный цикл реакции и методы render (), а также методы d3-selection (enter () , update (), exit ()) смешаны, чтобы управлять DOM. Это может привести к «удалению» элементов DOM, управляемых d3, с помощью алгоритма согласования виртуальных DOM / DOM react.js, как упоминалось выше.

Наше решение: Парадигма 1

В этом примере мы не используем методы d3-selection. Рендеринг и уничтожение элементов DOM лежит исключительно в области react.js. D3, что не менее важно, предоставляет свои математические функции для масштабирования и предварительной обработки данных. Обратите внимание, что вы можете столкнуться с проблемами при использовании инструментов преобразования и анимации d3. Вероятно, вам придется реализовать собственную методологию преобразования с помощью react.js. Однако существуют библиотеки анимации / преобразования react.js, которые могут вам помочь.