注意:我已经在那里发布了一个答案,我个人认为这是迄今为止最好的解决方案。虽然它不是最高级别的答案,但根据我得到的结果,它非常有效。
--------------------------------------------- 原始问题 ------------------------------------------- ------------
假设我正在编写一个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
状态发生了变化,所有帖子都被重新渲染,但其他方法可以我试试?
答案 0 :(得分:10)
您可以在extraData
中设置FlatList
:
<FlatList
...
extraData={this.state}
data={this.state.posts}
renderItem={this.renderPost}
...
/>
当state.posts
或state.posts
项目发生变化时,FlatList
会重新呈现。
用于告知列表重新呈现的标记属性(因为它实现了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 });
}