【问题标题】:Listview with section headers are not updating when data changes数据更改时,带有节标题的列表视图不会更新
【发布时间】:2016-05-23 07:30:53
【问题描述】:

我正在尝试使用节标题更新列表视图,但视图没有改变: https://rnplay.org/apps/WJ1cEw

这是我尝试更新列表视图的代码:

changeData(){
    var dataTemp = Object.assign({},data);
    dataTemp.Section1[0] = {title: 'New content for Row 1, Section 1'};
    this.setState({
        dataSource: this.state.dataSource.cloneWithRowsAndSections(dataTemp)
    });
}

我可以看到 rowHasChanged 正在运行,但 row1 和 row2 都包含新数据,因此它永远不会评估为真。

如果我总是从 rowHasChanged 返回 true,则更新 ListView,但我猜这意味着重新渲染整个 listView。

【问题讨论】:

  • 您需要提供更多上下文。具体来说,“数据”从何而来?我敢打赌它正在被 ref 修改,所以它已经改变了,因为它肯定没有在这个“changeData”函数中设置。
  • 我在上面的rnplay链接中提供了一个完整的例子和源代码。

标签: react-native


【解决方案1】:

首先,您不会从 rowHasChanged 函数返回任何内容:

    this.state = {
        dataSource: new ListView.DataSource({
            rowHasChanged : (row1, row2) => {
                console.log(row1.title + ' ' + row2.title);
                return row1 !== row2; // <--- MISSING RETURN
            },
            sectionHeaderHasChanged : (s1, s2) => s1 !== s2
        })
    };

其次,Object.assign 是浅合并。尽管您尝试使changeData 纯正,但您的数组仍然被 ref 踩在脚下。最好的选择是在每次调用 changeData 时根据实际数据的平面列表计算您的部分,而不是将部分存储为状态的一部分,但如果您想让它正常工作,您可以先使用 @987654321 进行深度克隆@。

changeData(){
    data = _.cloneDeep(data)

    data.Section1[0] = {title: 'New content for Row 1, Section 1'};
    this.setState({
        dataSource: this.state.dataSource.cloneWithRowsAndSections(data)
    });
}

我提到的更好的方法是使用 Array.prototype.reduce:

const data = data.reduce((blob, dataItem) => {
    const section = 'ComputedSectionLabel';
    blob[section] = blob[section] || [];
    blob[section].push(dataItem);
}, {});

this.setState({
    dataSource: this.state.dataSource.cloneWithRowsAndSections(data)
});

【讨论】:

    猜你喜欢
    • 2018-03-31
    • 2012-11-13
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 2016-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多