简体   繁体   English

React Native:当按下“like”按钮时,如何为呈现的 FlatList 中的每个项目处理 state?

[英]React Native: how to handle state for each item in a rendered FlatList when pressing the 'like' button?

I'm trying to handle the state for a 'heart' icon in a rendered Flat List (which loads data from Firebase) for each individual item within the Flat List.我正在尝试为平面列表中的每个单独项目处理 state 在呈现的平面列表(从 Firebase 加载数据)中的“心”图标。

The code works, in that the heart icon fills in and the data is pushed to the database when the icon is pressed.该代码有效,因为填充了心形图标,并在按下图标时将数据推送到数据库。 Likewise, pressing the heart icon again reverts the icon and removes the 'like' from the database.同样,再次按下心形图标将恢复图标并从数据库中删除“喜欢”。

However, when the heart icon is clicked, it swaps between the filled in state and hollow state for the heart icon for every item in the list, when I'm trying to alter state for that specific item.但是,当单击心形图标时,它会在填充的 state 和空心 state 之间切换,用于列表中每个项目的心形图标,当我尝试更改特定项目的 Z9ED39E2EA931586B6A985A6942EF5 时

I understand that I need to handle state locally for each item in the Flat List, but I've no idea how to do it.我知道我需要为 Flat List 中的每个项目在本地处理 state,但我不知道该怎么做。 Any help would be appreciated.任何帮助,将不胜感激。 Code below:下面的代码:

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>
    );
  }
}

becuase this.state.liked will be true for all items in the json respone to correct it you can update the state array json因为 this.state.liked 将适用于 json 响应中的所有项目以更正它,您可以更新 stateFCA366 数组

 ItemPRessed =(index)=>{let dataArray = this.state.data
  dataArray[index].liked = !dataArray[index].liked
  this.setState({
    data:dataArray
  })}

and instead of this.state.liked use post.liked so it will be specific to the item and instead of this.setState({liked: true});而不是this.state.liked使用post.liked所以它将特定于项目而不是this.setState({liked: true}); put

this.ItemPRessed(Index)

i don't know how your indexs work in your json put if it is like this我不知道你的索引在你的 json 中是如何工作的,如果是这样的话

[{item},{item}]

then you can use renderItem=({item: post, index}) instead of renderItem={({item: post})那么你可以使用renderItem=({item: post, index})而不是renderItem={({item: post})

to get the index on which item it is pressed then获取按下它的项目的索引

Ok so the issue is that you've got a singular liked state value instead of an array.好的,问题是你有一个单一的liked state 值而不是数组。 You should firstly change liked to an array (which will store the id of the posts which are liked).您应该首先将liked的内容更改为一个数组(它将存储被喜欢的帖子的 ID)。 Maybe call it something more appropriate such as likePosts .也许将其称为更合适的名称,例如likePosts Then you can add or remove post ids from the array when they're liked or unliked (and check the likedPosts array for the value when deciding what icon to display).然后,您可以在喜欢或不喜欢它们时从数组中添加或删除帖子 ID(并在决定显示什么图标时检查likedPosts数组的值)。

Your modified code should look something like this:您修改后的代码应如下所示:

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.

相关问题 渲染后如何在不刷新 React Native 上的其他项目的情况下更改 FlatList 项目的 state - How to change state of FlatList item after rendered without refreshing other item on React Native React Native Flatlist ListHeaderComponent 未在 state 更改上呈现 - React Native Flatlist ListHeaderComponent is not rendered on state change 如何在本机中处理平面清单项目数据? - How to handle flatlist item data in react-native? React-Native如何从平面列表中的项目处理onPress ??? - React-Native How to handle onPress from Item in flatlist ??? React Native:在行项目上按下切换按钮时重新呈现 FlatList - React Native: Rerender FlatList when toggle button is pressed on a row item 如何在 React Native FlatList 中一次处理一个按钮? - How to handle a single button at a time in React Native FlatList? 如何在 React Native 中为 Flatlist 中的单个项目启用按钮? - How to enable button for a single item in Flatlist in React native? 如何在 React Native 中使用 FlatList 滚动到按钮上的下一个项目? - How to scroll To next item on a button click using FlatList in React Native? 在React Native中按下按钮时如何更改FlatList项目背景颜色 - How can i change the FlatList item background color when button is pressed in React Native 对每个项目进行模态处理反应原生 Flatlist - React native Flatlist with modal handling for each item
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM