В React: Как использовать onBranchCollapsedRef для управления состоянием скрытых веток в больших иерархических структурах?
В React нет встроенного API с именем `onBranchCollapsedRef` как стандартного хука или свойства из коробки — это паттерн, который разработчики реализуют самостоятельно при работе с древовидными (иерархическими) структурами данных, такими как файловые деревья, меню навигации, организационные схемы и т.д.
## Что такое onBranchCollapsedRef?
`onBranchCollapsedRef` — это ref-коллбэк или объект `useRef`, который хранит ссылку на функцию-обработчик события сворачивания ветки дерева. Использование `ref` вместо обычного состояния или пропса позволяет избежать лишних ре-рендеров при изменении коллбэка.
## Зачем использовать ref вместо state?
При работе с большими иерархическими структурами (тысячи узлов) каждый лишний ре-рендер критичен. `useRef` позволяет:
— Хранить актуальную ссылку на коллбэк без перерисовки дерева
— Передавать стабильный обработчик в дочерние компоненты
— Избегать проблем с замыканиями (stale closure)
## Пример реализации
jsx
import React, { useRef, useCallback, useState } from ‘react’;
function TreeNode({ node, onBranchCollapsedRef }) {
const [collapsed, setCollapsed] = useState(false);
const handleToggle = useCallback(() => {
const newCollapsed = !collapsed;
setCollapsed(newCollapsed);
// Вызываем актуальный коллбэк через ref
if (newCollapsed && onBranchCollapsedRef.current) {
onBranchCollapsedRef.current(node.id);
}
}, [collapsed, node.id, onBranchCollapsedRef]);
return (
{!collapsed && node.children?.map(child => (
))}
);
}
function Tree({ data }) {
const [collapsedIds, setCollapsedIds] = useState(new Set());
const onBranchCollapsedRef = useRef(null);
// Обновляем ref при каждом рендере — коллбэк всегда актуален
onBranchCollapsedRef.current = useCallback((nodeId) => {
setCollapsedIds(prev => new Set([…prev, nodeId]));
}, []);
return ;
}
## Управление состоянием скрытых веток
Для больших деревьев рекомендуется:
1. **Хранить состояние централизованно** — в родительском компоненте или контексте (React Context)
2. **Использовать Set для хранения ID свёрнутых узлов** — O(1) поиск
3. **Виртуализация** — библиотеки `react-window` или `react-virtual` для рендеринга только видимых узлов
4. **Мемоизация узлов** через `React.memo` и `useMemo`
## Интеграция с Context
Для глубоких деревьев передача `onBranchCollapsedRef` через пропсы становится громоздкой. Используйте Context:
jsx
const TreeContext = React.createContext(null);
function TreeProvider({ children }) {
const onBranchCollapsedRef = useRef(null);
return (
{children}
);
}
Такой подход обеспечивает масштабируемость и производительность при работе с иерархиями любой глубины.
