反应本机列表视图 - 在不渲染整个列表的情况下预先添加项目

时间:2015-11-20 09:58:41

标签: react-native

我正在尝试使用pull to refresh功能实现无限滚动。 我获取了新数据,通过concat附加,并且呈现正常。问题是它用它呈现整个列表。如果我有> 500件物品,那就变成了一场噩梦。

onRefresh() {
    var posts = this.state.posts;
    var firstPost = posts[0].m._id;

    server.getStream('', firstPost, 4000)
        .then(res => {
             posts = res.concat(posts);
             this.setState({
                dataSource: this.ds.cloneWithRows(posts),
                posts
             });
             this.swipeRefreshLayout && this.swipeRefreshLayout.finishRefresh();
        })

}

有没有办法告诉RN只渲染新行?某种key道具可能吗?

由于

更新

DatSource中的rowHasChanged比较器不会触发。我认为我构建组件的方式可能与它有关。

renderRow(post) {

    if(post === 'loader') {
        return (
            <ProgressBarAndroid 
                styleAttr="Large" 
                style={styles.spinnerBottom}/>
        )
    }

    let hasLoader = post.m._id === lastPostId;

    let loader = hasLoader ? 
        <ProgressBarAndroid 
            styleAttr="Large" 
            style={styles.spinnerBottom}/> : null;

    return (
        <View>
            <Post 
                post={post}
                isLoadingTop={isLoadingTop}/>
            {loader}
        </View> 
    )
}

render() {

    var stream = <ListView
                    dataSource={this.state.dataSource}
                    renderRow={this.renderRow.bind(this)}
                    onEndReached={this.onEndReached.bind(this)}
                    onEndReachedThreshold={1}
                    pageSize={15} />


    return (
        <View style={styles.mainContainer}>
            <View style={styles.header}>
                <Text style={styles.headerText}>Header</Text>
            </View>
            <SwipeRefreshLayoutAndroid
                ref={(c) => { 
                    this.swipeRefreshLayout = c;
                }}
                onRefresh={this.onRefresh.bind(this)}>
                {stream}
            </SwipeRefreshLayoutAndroid>
        </View>
    );

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

您需要实现DataSource.rowHasChanged比较器,以便为数据未更改的行呈现false。如果现有列表项未更改,则可以使用简单的引用相等性检查:

let dataSource = new ListView.DataSource({
  rowHasChanged: (prev, next) => prev !== next
});

如果您不想更改的行与上一个渲染过程中使用的行不同,则需要实现更具体的比较器函数。