避免使用react-redux重新渲染大量项目

use*_*275 12 reactjs redux react-redux

我正在为我的应用程序使用redux with react和typescript.我正在使用我的应用程序的不同位置使用的许多项目.我的州看起来像这样:

{
    items: {42: {}, 53: {}, ... }, //A large dictionary of items
    itemPage1: {
        itemsId: [ 42, 34, 4 ],
        ...
    },
    itemPage2: { ... 
    },
    ...
}
Run Code Online (Sandbox Code Playgroud)

用户可以修改items调度某些操作的某些属性.当发生这种情况时,我需要重绘每个页面中已修改的组件.问题是我的物品很大,我不能在每次小修改时重新绘制所有物品.我想知道这种方法是否有效:

  • 我有一个<ItemPage1>连接到商店的拳头组件,以获取存储在树中的所有状态,itemPage1例如项目列表id : itemsId.
  • 在里面<ItemPage1>,我遍历itemsId属性以生成多个FilterItem组件:itemsId.map( itemId => return <FilterItem id=itemId>);
  • 最后,每个Item都使用连接ownProps来获取状态的正确部分:

    const mapStateToItemProps = (state, ownProps) => {
        return {
            item: state.items[ownProps.id],
        }
    }
    const mapDispatchToItemProps = (dispatch, ownProps) => {
        return null;
    }
    const FilterItem = connect(
        mapStateToItemProps,
        mapDispatchToItemProps
    )(Item)
    
    Run Code Online (Sandbox Code Playgroud)

你能否确认或反驳如果我更新了id 42的项目,那么只有这个项目会被重新渲染?

Pie*_*scy 12

渲染大型列表时,您需要考虑以下几点:

  • 降低需要渲染的DOM元素总数(通过不渲染屏幕上实际不可见的项目,也称为虚拟化)
  • 不要重新渲染未更改的项目

基本上,当用户编辑单行时,您要避免的是完全重新呈现列表(或页面).这可以完全按照您的方式实现,即:通过仅向需要渲染的项目的ID传递给列表容器,并connect通过使用将这些ID映射到每个组件ownProps.如果您有转储<Item/>组件,则<ItemPage/>组件将创建连接connect(<Item/>)组件.

这是有效的,如果你console.log('item rendered')<Item/>组件类中放入一个,你会注意到只有一个调用.

但是(这是一个很大但是),在使用时不明显的react-redux是,如果状态的任何部分发生变化,依赖于它们的所有连接组件ownProps始终重新呈现.在您的情况下,即使<Item/>组件不会重新渲染,它们的包装组件connect(Item)也会!如果您有几十个项目,如果需要快速调度操作(例如输入输入时),可能会遇到一些延迟.怎么避免呢?使用工厂函数ownProps作为初始道具:

const mapStateToItemProps = (_, initialProps) => (state) => {
    return {
        item: state.items[initialProps.id],  // we're not relying on the second parameters "ownProps" here, so the wrapper component will not rerender
    }
}
const mapDispatchToItemProps = (dispatch, ownProps) => {
    return null;
}
const FilterItem = connect(
    mapStateToItemProps,
    mapDispatchToItemProps
)(Item)
Run Code Online (Sandbox Code Playgroud)

我建议你看看另一个答案.

您可能也对这些出色的幻灯片感兴趣:Big List High Performance React&Redux

最后,您应该明确地看一下反应虚拟化以执行列表的虚拟化(即,仅显示用户可以实际看到的项目).