Простой D3 с React Hooks
Компоненты функции React с хуками дает нам хороший способ интегрировать D3 с React. Есть много связанных статей, которые уже описывают это, но они быстро попадают в сорняки и усложняются. Эта статья - всего лишь основы того, как правильно начать работу. Вы можете расширяться оттуда.
Раньше было сложно найти правильные места для размещения кода D3, особенно для тех, кто плохо знаком с D3, все еще ломая голову над тем, как D3 делает что-то. Оптимизация для минимизации повторного рендеринга была сложной задачей, хотя это должно быть легко.
Функциональные компоненты с хуками немного проясняют это. Есть одно место для размещения D3, один способ подключить его к React DOM, и логика повторного рендеринга в основном встроена.
useRef Hook
Мы создаем функцию, а не класс. Переменных-членов класса нет, поэтому нам нужен способ удерживать объект на нескольких проходах рендеринга.
useRef()
создает переменную, которая делает именно это. Переменная действует во многом как переменная-член класса без класса. Мы будем использовать useRef (), чтобы удерживать элемент DOM, содержащий наш контент D3. Ссылка «получить» и «установить» через свойство .current
.
useEffect Hook
useEffect()
дает нам место для размещения побочных эффектов, таких как наш код D3. Побочный эффект?! Это побочный эффект, потому что он добавляет контент в DOM за пределами виртуального механизма DOM React. (Примечание: useEffect()
похож на componentDidMount()
и componentWillReceiveProps()
combined, с обнаружением изменений как первоклассной функцией.)
Вот полный пример хуков и D3 (машинописный текст):
Вот что делает пример:
Вызовите useRef (), чтобы создать переменную (d3Container
) для хранения элемента SVG. Инициализируйте его как null
. React установит его при первом отображении страницы (потому что мы указываем это в строке кода 60).
Почему бы просто не использовать d3.select()
для получения элемента SVG или вставить элемент SVG, используя чистый D3? Используя переменную ref, мы можем использовать ее как зависимость в нашем блоке useEffect()
, чтобы определить, когда элемент на самом деле были отрисованы и доступны.
Вызовите useEffect (), чтобы выполнить наш код D3. useEffect()
принимает два аргумента - функцию для запуска и массив переменных зависимости. useEffect()
будет запускаться каждый раз при изменении одной из переменных зависимости (очень похоже на вычисляемые свойства в Ember и Vue, если вы когда-либо их использовали). Поскольку мы указали data
как зависимость, useEffect()
будет запускаться снова при изменении data
. Нам больше не нужно писать код для сравнения старых и новых данных на предмет изменений!
Компонент функции возвращает элемент SVG, а его атрибут ref
установлен в d3Container
- переменную ref, которую мы объявили в верхней части функции.
React запустит наш код D3, когда DOM будет готов и когда данные изменятся.