首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对数组使用useCallback/useMemo

对数组使用useCallback/useMemo
EN

Stack Overflow用户
提问于 2019-08-27 15:41:10
回答 1查看 5.2K关注 0票数 0

我在我的应用程序中遇到了性能问题。原因是我使用的useCallback有很多deps,如下所示

代码语言:javascript
复制
const getTreeData = React.useCallback((tree: Area.Model[]): TreeItem[] => {
        let treeData: TreeItem[] = [];
        if (tree) {
            treeData = {
                flatData: tree.map(
                    (area): any => {
                        const areaKey = getKeyForArea(area.id, area.type, area.closestGroupId);
                        return {
                            id: area.id,
                            name: area.name,
                            type: area.type,
                            title: (
                                <TreeTitle
                                    id={area.id}
                                    key={area.id}
                                    type={area.type}
                                    title={area.name}
                                    closestGroupId={area.closestGroupId}
                                    expandable={area.drillableDirections !== undefined && area.drillableDirections.includes(Drill.Direction.DOWN)}
                                    status={status[areaKey]}
                                    counter={subAreas[areaKey]}
                                    unselectedStoreCounter={unselectedStoreCounter[areaKey]}
                                    onAggregationButtonClick={handleAggregateOptionToggle}
                                    onQuickAggregationOptionForSubGroups={handleQuickAggregateOptionForSubGroupsToggle}
                                    onQuickAggregationOptionForSubStores={handleQuickAggregateOptionForSubStoresToggle}
                                />
                            ),
                            parent: area.closestGroupId,
                            expanded: status[areaKey].isExpanded,
                        };
                    },
                ),
                getKey: (node: any): number => node.id,
                getParentKey: (node: any): number => node.parent || 0,
                rootKey: 0,
            };
        }
        return treeData;
    }, [status, subAreas, unselectedStoreCounter, handleAggregateOptionToggle, handleQuickAggregateOptionForSubGroupsToggle, handleQuickAggregateOptionForSubStoresToggle]);

如您所见,所有依赖项都在代码中使用。然而,每次有变化,将只有一个元素更新,但整个函数将重新运行并返回一个全新的对象,这将触发我的渲染函数在另一个地方。

因此,我的问题是:有没有办法让我使用useCallbackuseMemo来优化这段代码?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-27 16:45:00

我认为你性能问题的根本原因是你挂载了太多的dom元素。我也有同样的问题,并通过虚拟化树来解决它。我使用了react-virtualized-tree来做这件事,下面是它的工作原理。

VirtualizedTree.js

代码语言:javascript
复制
import React from 'react';
import PropTypes from 'prop-types';

import Tree from 'react-virtualized-tree/lib/Tree';
import TreeStateModifiers from 'react-virtualized-tree/lib/state/TreeStateModifiers'
import { UPDATE_TYPE } from 'react-virtualized-tree/lib/contants'
import { Node } from 'react-virtualized-tree/lib/shapes/nodeShapes';

export default class UnstableFastTree extends React.Component {
  static contextTypes = {
    unfilteredNodes: PropTypes.arrayOf(PropTypes.shape(Node))
  };

  get nodes() {
    return this.context.unfilteredNodes || this.props.nodes;
  }

  handleChange = ({ node, type, index }) => {
    let nodes;

    if (type === UPDATE_TYPE.UPDATE) {
      nodes = TreeStateModifiers.editNodeAt(this.props.nodes, index, node);
    } else {
      nodes = TreeStateModifiers.deleteNodeAt(this.props.nodes, index);
    }

    this.props.onChange(nodes);
  };

  render() {
    return (
      <Tree
        nodeMarginLeft={this.props.nodeMarginLeft}
        nodes={this.props.nodes}
        onChange={this.handleChange}
        NodeRenderer={this.props.children}
      />
    );
  }
}

UnstableFastTree.propTypes = {
  extensions: PropTypes.shape({
    updateTypeHandlers: PropTypes.object
  }),
  nodes: PropTypes.shape({
    flattenedTree: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.oneOf([PropTypes.number, PropTypes.string])))
      .isRequired,
    tree: PropTypes.arrayOf(PropTypes.shape(Node)).isRequired
  }),
  onChange: PropTypes.func,
  children: PropTypes.func.isRequired,
  nodeMarginLeft: PropTypes.number,
  width: PropTypes.number,
  scrollToId: PropTypes.number
};

UnstableFastTree.defaultProps = {
  nodeMarginLeft: 30
};

Tree.js

代码语言:javascript
复制
import React, { useMemo } from 'react'
import PropTypes from 'prop-types'
import pick from 'lodash/pick'
import VirtualizedTree from '@controls/VirtualizedTree'
import TreeState from 'react-virtualized-tree/lib/state/TreeState'
import TreeNode from './TreeNode'

export default function BrowseTree(props) {
  const {
    treeData
  } = props
  const getAllNodes = all => all.reduce((acc, el) => [
    ...acc,
    el,
    ...(el.collapse ? getAllNodes(el.children) : [])
  ], [])
  const nodes = useMemo(() => TreeState.createFromTree(treeData), [treeData])
  const treeProps = pick(props, [
    'type', 'selectedNodeId', 'onNodeClick', 'onHideDialog', 'onShowDialog',
    'browseToggle', 'disableIds', 'config', 'fetching', 'topicIcon', 'role'
  ])
  return (
    <VirtualizedTree nodes={nodes}>
      {({ style, node }) => (
        <TreeNode
          key={node.db_id}
          style={style}
          node={node}
          {...treeProps}
        />
      )}
    </VirtualizedTree>
  )
}

BrowseTree.propTypes = {
  type: PropTypes.string.isRequired,
  treeData: PropTypes.array.isRequired
}

我希望这能帮到你。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57669866

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档