#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 — да, данные будут мутировать. Интересно, хорошо.