在React中使用嵌套列表递归渲染-如何避免不必要的更新?

时间:2018-10-27 06:48:35

标签: javascript reactjs recursion redux immutability

我有一个list对象处于还原状态。它具有如下所示的byId集:

{
    root: {
        id: 'root',
        children: ['item_1', 'item_2'],
        data: 'Root String',
        parent: null,
    },
    item_1: {
        id: 'item_1',
        children: ['item_1_1', 'item_1_2', 'item_1_3'],
        data: 'Some String',
        parent: 'root',
    },
    item_1_1:
    {
        id: 'item_1_1'
        children: ['item_1_1_1', 'item_1_1_2']
        data: 'Some Other string',
        parent: 'item_1',
    },
    item_2: {
        ...
    }
    ...
}

现在,我将上述列表呈现如下:

render()

recursiveRender = (component, idx = 0) => {
    const { data, children } = component;
    const { list } = this.props; 
    return (
        <div key={idx}>
            {
                children.map((child, childIdx) =>
                    this.recursiveRender(list[child], childIdx))
            }
        </div>
    );
};

render() {
    const { list } = this.props;
    return this.recursiveRender(list.root);
}

Redux Reducer

我想更新item_1的子级的顺序。

我在redux操作中执行以下操作:

import update from 'immutability-helper';
...
...
return update(state,
    {
        list: {
            [parent]: {
                children: {
                    $splice: [[oldIdx, 1], [idx, 0, id]] },
                },
        },
    }
});

有效。

问题

我在React Dev Tools中注意到,递归渲染的组件的每个item_2item_3也都被重新绘制了)。我不知道为什么。我确保list是不变的,但是每次都再次渲染整个树。如何确定item_1的更改部分(此处为list)才重新粉刷?

我不认为使用reselect是这里的解决方案,因为列表 确实在变化。

那么,我应该有一个动态的mapStateToProps吗?如果是这样,如何不更改依赖于list的其他列表项?还是我看错地方了,问题可能出在应用程序的其他地方。

1 个答案:

答案 0 :(得分:0)

无状态功能组件在旧道具和新道具之间不做任何比较。一种简单的解决方案是改为将RecursiveRender用作root.myfunc() root.submodule.another_func()