DOM и React Senior Компоненты на практике обновлено

Дерево с трёхсостоянием

Условие

Дерево узлов { id, name, children } с чекбоксами. Требования: · узел - <li data-id>, чекбокс внутри - <input type="checkbox" data-cb={id}>; · отметка родителя отмечает всех потомков, снятие - снимает; · если отмечена часть потомков, родитель в неопределённом состоянии (indeterminate) и не отмечен; · если отмечены все потомки, родитель отмечен; · onChange(массивОтмеченныхЛистьев) при каждом изменении, только листья, порядок обхода.

Что проверяют тесты

  • рисует дерево

  • отметка родителя отмечает потомков

  • частичная отметка даёт неопределённое состояние

  • все потомки отмечены - родитель отмечен

  • работает на любой глубине

  • наружу уходят только листья

  • снятие родителя снимает потомков

Как подойти

Ключевое решение - единственный источник правды: множество отмеченных листьев. Состояние любого родителя выводится подсчётом отмеченных листьев в его поддереве, поэтому рассинхрон невозможен в принципе. Хранить отметки для всех узлов значит поддерживать согласованность вручную при каждом клике. Второй момент: indeterminate существует только как свойство DOM-узла, разметкой его не выразить - отсюда ref плюс эффект. Что назвать вслух: мемоизация подсчёта листьев на больших деревьях, ленивая подгрузка ветвей, роли treeitem с aria-checked.

Подсказки: 3
  1. Храни отметки только для листьев - состояние родителей выводится.
  2. indeterminate нельзя задать атрибутом, только свойством узла - понадобится ref и эффект.
  3. Переключение узла означает переключение всех его листьев разом.

Решите в тренажёре

Редактор с автотестами прямо в браузере. Можно решить спокойно, вслух или под таймером, как на собесе.