Простой 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 будет готов и когда данные изменятся.