![](/img/trans.png)
[英]How to change state of FlatList item after rendered without refreshing other item on React Native
[英]React Native: how to handle state for each item in a rendered FlatList when pressing the 'like' button?
我正在尝试为平面列表中的每个单独项目处理 state 在呈现的平面列表(从 Firebase 加载数据)中的“心”图标。
该代码有效,因为填充了心形图标,并在按下图标时将数据推送到数据库。 同样,再次按下心形图标将恢复图标并从数据库中删除“喜欢”。
但是,当单击心形图标时,它会在填充的 state 和空心 state 之间切换,用于列表中每个项目的心形图标,当我尝试更改特定项目的 Z9ED39E2EA931586B6A985A6942EF5 时
我知道我需要为 Flat List 中的每个项目在本地处理 state,但我不知道该怎么做。 任何帮助,将不胜感激。 下面的代码:
import React, {Component} from 'react';
import {
FlatList,
Text,
View,
} from 'react-native';
import {Icon} from 'react-native-elements';
import {globalStyles} from '../config/Styles';
import Firebase from 'firebase';
import 'firebase/database';
export default class HomeScreen extends Component {
constructor(props) {
super(props);
this.state = {
//set value of postList variable as an empty array
postList: [],
liked: false,
};
}
componentDidMount() {
this.getPostData();
}
getPostData = () => {
const ref = Firebase.database().ref('/posts');
ref.on('value', snapshot => {
const postsObject = snapshot.val();
if (!postsObject) {
console.log('NO DATA IN FIREBASE:', Date(Date.now()));
} else {
console.log('HOMESCREEN FIREBASE DATA RETRIEVED:', Date(Date.now()));
const postsArray = Object.values(postsObject);
this.setState({postList: postsArray});
}
});
};
render() {
return (
<View>
<FlatList
keyExtractor={post => post.id}
data={this.state.postList}
renderItem={({item: post}) => (
<View style={globalStyles.postContainer}>
<Text style={globalStyles.postText}>
{post.heading}
{'\n'}@{' '}
<Text style={{fontWeight: 'bold'}}>{post.location}</Text>
{'\n'}
{post.description}
{'\n'}
listed by{' '}
<Text style={{fontWeight: 'bold'}}>{post.createdBy}</Text>
{'\n'}
on <Text style={{fontWeight: 'bold'}}>{post.createdAt}</Text>
</Text>
<View style={globalStyles.iconMargin}>
<Icon
raised
iconStyle={globalStyles.icon}
name={this.state.liked ? 'heart' : 'heart-o'}
size={28}
type="font-awesome"
onPress={() => {
const userKey = Firebase.auth().currentUser.uid;
const postKey = post.id;
const favRef = Firebase.database().ref(
'favourites/' + userKey + '/' + postKey,
);
if (this.state.liked === false) {
favRef.set({
id: postKey,
heading: post.heading,
description: post.description,
location: post.location,
createdAt: post.createdAt,
createdBy: post.createdBy,
});
this.setState({liked: true});
} else {
favRef.remove();
this.setState({liked: false});
}
}}
/>
<Icon
raised
iconStyle={globalStyles.icon}
name="flag-o"
size={28}
type="font-awesome"
onPress={() =>
this.props.navigation.navigate('ReportPostScreen', post)
}
/>
</View>
</View>
)}
/>
</View>
);
}
}
因为 this.state.liked 将适用于 json 响应中的所有项目以更正它,您可以更新 stateFCA366 数组
ItemPRessed =(index)=>{let dataArray = this.state.data
dataArray[index].liked = !dataArray[index].liked
this.setState({
data:dataArray
})}
而不是this.state.liked
使用post.liked
所以它将特定于项目而不是this.setState({liked: true});
放
this.ItemPRessed(Index)
我不知道你的索引在你的 json 中是如何工作的,如果是这样的话
[{item},{item}]
那么你可以使用renderItem=({item: post, index})
而不是renderItem={({item: post})
获取按下它的项目的索引
好的,问题是你有一个单一的liked
state 值而不是数组。 您应该首先将liked
的内容更改为一个数组(它将存储被喜欢的帖子的 ID)。 也许将其称为更合适的名称,例如likePosts
。 然后,您可以在喜欢或不喜欢它们时从数组中添加或删除帖子 ID(并在决定显示什么图标时检查likedPosts
数组的值)。
您修改后的代码应如下所示:
import React, {Component} from 'react';
import {
FlatList,
Text,
View,
} from 'react-native';
import {Icon} from 'react-native-elements';
import {globalStyles} from '../config/Styles';
import Firebase from 'firebase';
import 'firebase/database';
export default class HomeScreen extends Component {
constructor(props) {
super(props);
this.state = {
//set value of postList variable as an empty array
postList: [],
likedPosts: [],
};
}
componentDidMount() {
this.getPostData();
}
getPostData = () => {
const ref = Firebase.database().ref('/posts');
ref.on('value', snapshot => {
const postsObject = snapshot.val();
if (!postsObject) {
console.log('NO DATA IN FIREBASE:', Date(Date.now()));
} else {
console.log('HOMESCREEN FIREBASE DATA RETRIEVED:', Date(Date.now()));
const postsArray = Object.values(postsObject);
this.setState({postList: postsArray});
}
});
};
render() {
return (
<View>
<FlatList
keyExtractor={post => post.id}
data={this.state.postList}
renderItem={({item: post}) => (
<View style={globalStyles.postContainer}>
<Text style={globalStyles.postText}>
{post.heading}
{'\n'}@{' '}
<Text style={{fontWeight: 'bold'}}>{post.location}</Text>
{'\n'}
{post.description}
{'\n'}
listed by{' '}
<Text style={{fontWeight: 'bold'}}>{post.createdBy}</Text>
{'\n'}
on <Text style={{fontWeight: 'bold'}}>{post.createdAt}</Text>
</Text>
<View style={globalStyles.iconMargin}>
<Icon
raised
iconStyle={globalStyles.icon}
name={this.state.likedPosts.indexOf(post.id) > -1 ? 'heart' : 'heart-o'}
size={28}
type="font-awesome"
onPress={() => {
const userKey = Firebase.auth().currentUser.uid;
const postKey = post.id;
const favRef = Firebase.database().ref(
'favourites/' + userKey + '/' + postKey,
);
// This checks that the array doesn't contain the post id (i.e. the post was not previously liked)
if (this.state.likedPosts.indexOf(post.id) === -1) {
favRef.set({
id: postKey,
heading: post.heading,
description: post.description,
location: post.location,
createdAt: post.createdAt,
createdBy: post.createdBy,
});
// Include the post.id in the likedPosts array
this.setState({ likedPosts: [...this.state.likedPosts, post.id] })
} else {
favRef.remove();
// Remove the post.id from the likedPosts array
let index = this.state.likedPosts.indexOf(post.id);
this.setState({ likedPosts: this.state.likedPosts.splice(index, 1) })
}
}}
/>
<Icon
raised
iconStyle={globalStyles.icon}
name="flag-o"
size={28}
type="font-awesome"
onPress={() =>
this.props.navigation.navigate('ReportPostScreen', post)
}
/>
</View>
</View>
)}
/>
</View>
);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.