Как отрисовать раскрывающееся дерево сообщений в React?

Рекурсивный компонент хранит open для своего узла и рендерит детей только при раскрытии. Кнопка нужна лишь узлам с непустыми children; ключом служит id.

Короткий ответ

Что ответить на собеседовании

Рекурсивный компонент хранит open для своего узла и рендерит детей только при раскрытии. Кнопка нужна лишь узлам с непустыми children; ключом служит id.

Подробный разбор

Ответ с пояснениями

Условие

Данные имеют форму {id, text, children?: Node[]}, id уникален. Нужно показать конечное дерево без циклов: родитель раскрывается по кнопке, лист показывает только текст. Изначально все ветви закрыты. Приведите компонент узла для произвольной вложенности.

Ответ

Рекурсивный компонент хранит open для своего узла и рендерит детей только при раскрытии. Кнопка нужна лишь узлам с непустыми children; ключом служит id.

import {useState} from 'react';
function TreeNode({node}) {
  const [open, setOpen] = useState(false);
  const children = node.children ?? [];
  return <li>
    {children.length ? <button type="button" aria-expanded={open}
      onClick={() => setOpen(v => !v)}>{node.text}</button> : <span>{node.text}</span>}
    {open && children.length > 0 && <ul>{children.map(child =>
      <TreeNode key={child.id} node={child} />)}</ul>}
  </li>;
}

Корневые узлы помещают в ul. Здесь сворачивание размонтирует потомков и сбрасывает их open; для сохранения раскрытия между закрытиями состояние выносят в словарь по id.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее