如何在React Native中更新FlatList中的单个项目?

时间:2017-10-28 20:39:21

标签: react-native

注意:我已经在那里发布了一个答案,我个人认为这是迄今为止最好的解决方案。虽然它不是最高级别的答案,但根据我得到的结果,它非常有效。

--------------------------------------------- 原始问题 ------------------------------------------- ------------

假设我正在编写一个Twitter克隆,但更简单。我将每个项目放在FlatList中并渲染它们。

为了“喜欢”一个帖子,我按下帖子上的“喜欢”按钮,“喜欢”按钮变成红色,我再次按下它,它变成灰色。

这就是我到目前为止:我将所有已加载的帖子存储在this.state中,每个帖子都有一个名为“likes”的属性,它是布尔值,表示此用户是否喜欢此帖子,用户按“喜欢”,我转到state.posts并更新该帖子的liked属性,然后使用this.setState更新帖子,如下所示:

// 1. FlatList
<FlatList
    ...
    data={this.state.posts}
    renderItem={this.renderPost}
    ...
/> 

// 2. renderPost
renderPost({ item, index }) {
    return (
        <View style={someStyle}>
            ... // display other properties of the post
            // Then display the "like" button
            <Icon
                name='favorite'
                size={25}
                color={item.liked ? 'red' : 'gray'}
                containerStyle={someStyle}
                iconStyle={someStyle}
                onPress={() => this.onLikePost({ item, index })}
            />
            ...
        </View>
    );
}

// 3. onLikePost
likePost({ item, index }) {
    let { posts } = this.state;
    let targetPost = posts[index];

    // Flip the 'liked' property of the targetPost
    targetPost.liked = !targetPost.liked;

    // Then update targetPost in 'posts'
    posts[index] = targetPost;

    // Then reset the 'state.posts' property
    this.setState({ posts });
}

然而,这种方法很有效。当我按下它时,“喜欢”按钮的颜色翻转,但通常需要大约1秒钟才能改变颜色。我想要的是当我按下它时,颜色几乎会同时翻转。

我知道为什么会发生这种情况,我可能不会使用this.setState,因为当我这样做时,posts状态发生了变化,所有帖子都被重新渲染,但其他方法可以我试试?

2 个答案:

答案 0 :(得分:10)

您可以在extraData中设置FlatList

<FlatList
...
    extraData={this.state}
    data={this.state.posts}
    renderItem={this.renderPost}
    ...
/> 

state.postsstate.posts项目发生变化时,FlatList会重新呈现。

来自FlatList#extradata

  

用于告知列表重新呈现的标记属性(因为它实现了PureComponent)。如果你的任何renderItem,Header,Footer等函数依赖于数据道具之外的任何东西,请将它贴在这里并对其进行不可变处理。

答案 1 :(得分:8)

如果您在Android上进行测试,请尝试关闭开发者模式。或者您是否正在使用某些API并更新服务器上的帖子并更新与服务器响应相对应的UI中的like按钮?如果是这种情况请告诉我,我也遇到了这个并且我解决了它。另外,我已经在代码中注释了第二行,这是不需要的。

// 1. FlatList
<FlatList
    ...
    data={this.state.posts}
    renderItem={this.renderPost}
    ...
/> 

// 2. renderPost
renderPost({ item, index }) {
    return (
        <View style={someStyle}>
            ... // display other properties of the post
            // Then display the "like" button
            <Icon
                name='favorite'
                size={25}
                color={item.liked ? 'red' : 'gray'}
                containerStyle={someStyle}
                iconStyle={someStyle}
                onPress={() => this.onLikePost({ item, index })}
            />
            ...
        </View>
    );
}

// 3. onLikePost
likePost({ item, index }) {
    let { posts } = this.state;
    let targetPost = posts[index];

    // Flip the 'liked' property of the targetPost
    targetPost.liked = !targetPost.liked;

    // Then update targetPost in 'posts'
    // You probably don't need the following line.
    // posts[index] = targetPost;

    // Then reset the 'state.posts' property
    this.setState({ posts });
}