【问题标题】:How to avoid re-renders in nested lists in React如何避免在 React 的嵌套列表中重新渲染
【发布时间】:2017-08-01 09:14:23
【问题描述】:

我有分层的、递归的数据结构。这是一个命名项目的列表,每个项目都可以有自己的项目子列表。它看起来像这样:

const items = [
    {
        name: 'item1',
        items: [
            {name: 'item2'},
            {name: 'item3'},
            {name: 'item4', items: [
                {
                    name: 'item5'
                }
            ]},
        ]
    },
    {
        name: 'item6'
    }
]

我想将它显示在带有嵌套子列表的无序列表中。此外,我需要能够将某些项目标记为突出显示并取消突出显示所有项目。由于第二个要求,有关突出显示的项目的信息必须存在于顶级组件中。

我的幼稚实现如下所示:

class App extends Component {
    constructor() {
        super(...arguments)
        this.state = {
            items: items,
            highlightedItemsNames: {},
        }
        this.handleHighligtItem = (item) => {
            this.setState({highlightedItemsNames: {
                ...this.state.highlightedItemsNames, [item.name]: true
            }})
        }
        this.handleDehighlightAllItems = () => {
            this.setState({highlightedItemsNames: {}})
        }
    }

    render() {
        return <div>
            <button onClick={this.handleDehighlightAllItems}>dehighlight</button>
            <List
                items={this.state.items}
                highlightedItemsNames={this.state.highlightedItemsNames}
                onHighlight={this.handleHighligtItem}
            />
        </div>
    }
}


function List(props) {
    return <ul>
        {props.items.map(item => <li key={item.name}>
            <Item
                item={item}
                highlighted={props.highlightedItemsNames[item.name]}
                highlightedItemsNames={props.highlightedItemsNames}
                onHighlight={props.onHighlight}
            />
        </li>)}
    </ul>
}


function Item(props) {
    let className = "item"
    if (props.highlighted) {
        className += '-highlighted'
    }
    console.log('renders item', props.item.name)
    return <div>
        <span className={className}>{props.item.name}</span>
        <button onClick={() => props.onHighlight(props.item)}>highlight</button>
        {props.item.items ? <List
            items={props.item.items}
            highlightedItemsNames={props.highlightedItemsNames}
            onHighlight={props.onHighlight}
        /> : null}
    </div>
}

但是现在,当我突出显示一个项目时,highlightedItemsNames 会发生变化,并且每个 Item 都会重新渲染。要正确显示数据,只有突出显示的项目及其父项需要重新渲染。那么如何避免所有这些不必要的重新渲染呢?

在我的应用程序中,项目列表可能有点大,重新渲染所有项目会导致应用程序在点击时明显冻结。

我可以在Item 中实现shouldComponentUpdate 来检查是否应该重新渲染任何子项,但这是否真的有机会提高virtual-dom 的性能?

我没有使用 Redux 或任何其他状态管理库,我现在不想这样做。

【问题讨论】:

  • 您需要为元素设置唯一键。否则它总是会重新渲染。
  • @MuratK。项目名称是唯一的 - 所以我在
  • 上有唯一的道具
  • @FabioAntunes 我没有使用 Redux
  • 标签: javascript reactjs


    【解决方案1】:

    ShouldComponentUpdate 用于检查和决定是否需要重新渲染。在大型项目不必要地重新渲染的情况下实施显然是一个明智的决定。我想您应该尝试实现此事件并查看性能。我相信尝试是使大多数事情变得完美的原因。

    【讨论】:

      猜你喜欢
      相关资源
      最近更新 更多
      热门标签