Добавление useCallback или useMemo в дерево рекурсивных материалов

#reactjs #recursion #react-hooks

Вопрос:

Мне интересно, как лучше всего реализовать функцию useCallback() или useMemo() для повышения производительности в компоненте treeview пользовательского интерфейса material. Этот пример невелик, но в моей реальной версии может быть 100 каталогов…

 import * as React from 'react';
import TreeView from '@mui/lab/TreeView';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
import TreeItem from '@mui/lab/TreeItem';

const data = {
  id: 'root',
  name: 'Parent',
  children: [
    {
      id: '1',
      name: 'Child - 1',
    },
    {
      id: '3',
      name: 'Child - 3',
      children: [
        {
          id: '4',
          name: 'Child - 4',
        },
      ],
    },
  ],
};

export default function RichObjectTreeView() {
  const renderTree = (nodes) => (
    <TreeItem key={nodes.id} nodeId={nodes.id} label={nodes.name}>
      {Array.isArray(nodes.children)
        ? nodes.children.map((node) => renderTree(node))
        : null}
    </TreeItem>
  );

  return (
    <TreeView
      aria-label="rich object"
      defaultCollapseIcon={<ExpandMoreIcon />}
      defaultExpanded={['root']}
      defaultExpandIcon={<ChevronRightIcon />}
      sx={{ height: 110, flexGrow: 1, maxWidth: 400, overflowY: 'auto' }}
    >
      {renderTree(data)}
    </TreeView>
  );
}

 

Комментарии:

1. Является data ли статичным? Если это так, вы можете перейти renderTree(data) в useMemo(() => renderTree(data), [data]) который позвоните renderTree только один раз. Если data вы можете мутировать, и вам нужно провести глубокое сравнение, все становится сложнее.

2. ^ Обратите внимание, что вам все равно нужно следовать правилам хуков . например, не вызывайте useMemo как часть условного рендеринга и не вызывайте его внутри циклов. Чтобы лучше продемонстрировать, что вышеизложенное по-прежнему соответствует правилам, вы можете сначала сохранить возвращаемое значение в переменной за пределами JSX. const treeItems = useMemo(() => renderTree(data), [data]) , затем поместите {treeItems} в свой JSX.

3. @3limin4t0r — да, данные будут мутировать. Интересно, хорошо.