Дерево с трёхсостоянием
Условие
Дерево узлов { id, name, children } с чекбоксами. Требования: · узел - <li data-id>, чекбокс внутри - <input type="checkbox" data-cb={id}>; · отметка родителя отмечает всех потомков, снятие - снимает; · если отмечена часть потомков, родитель в неопределённом состоянии (indeterminate) и не отмечен; · если отмечены все потомки, родитель отмечен; · onChange(массивОтмеченныхЛистьев) при каждом изменении, только листья, порядок обхода.
Что проверяют тесты
рисует дерево
отметка родителя отмечает потомков
частичная отметка даёт неопределённое состояние
все потомки отмечены - родитель отмечен
работает на любой глубине
наружу уходят только листья
снятие родителя снимает потомков
Как подойти
Ключевое решение - единственный источник правды: множество отмеченных листьев. Состояние любого родителя выводится подсчётом отмеченных листьев в его поддереве, поэтому рассинхрон невозможен в принципе. Хранить отметки для всех узлов значит поддерживать согласованность вручную при каждом клике. Второй момент: indeterminate существует только как свойство DOM-узла, разметкой его не выразить - отсюда ref плюс эффект. Что назвать вслух: мемоизация подсчёта листьев на больших деревьях, ленивая подгрузка ветвей, роли treeitem с aria-checked.
Подсказки: 3
- Храни отметки только для листьев - состояние родителей выводится.
- indeterminate нельзя задать атрибутом, только свойством узла - понадобится ref и эффект.
- Переключение узла означает переключение всех его листьев разом.
Решите в тренажёре
Редактор с автотестами прямо в браузере. Можно решить спокойно, вслух или под таймером, как на собесе.