bzlight
bzlight

Reputation: 1150

Data recorded from FlatList empty on first TouchableOpacity push

Summary of Problem

Inside of my Flatlist, I want to save the value of the row the user has clicked on in an array

Each row of my FlatList is clickable by using TouchableOpaicty.

What I've tried

I've searched the internet without finding any answer and I've tried saving the data to an array in many different ways

Code

FlatList

    <FlatList
                        data={this.state.friends}
                        renderItem={({item}) => {
                            console.log('item', item);
                            return( 
                                <TouchableOpacity
                                onPress={() => this.add(item.key)}
                            >
                                <ImageBackground
                                    style={styles.friendBubble}
                                    source={require('../../assets/images/friendDisplay.png')}
                                >
                                    <Text style={styles.friendText}>{item.key}</Text>
                                </ImageBackground>
                            </TouchableOpacity>
                            )
                        }}
                    />

TouchableOpacity onPress function

add = (item) => {
        this.setState(
            {friendsInComp: [...this.state.friends, item]}, 
            console.log('this.state.friend', this.state.friendsInComp)
        )
    }

Expected Results

Each time I click a row, the value of that row should be appended to the end of the array.

Actual Results

The first time a row is clicked, no value is added to the array. Each subsequent time the row is clicked, the value from the previous click is added to the end of the array.

Upvotes: 0

Views: 102

Answers (1)

Hazim Ali
Hazim Ali

Reputation: 1095

The reason why the first time you click the button, your console log print undefined is because setState is asynchronous.. thus it directly print the state without waiting the setState to finish the process, if you want to see the latest state after setState finish, you need to put the console.log inside function..

add = (item) => {
  this.setState({
    friendsInComp: [...this.state.friends, item ]},
    () => { console.log('this.state.friend', this.state.friendsInComp) }
  )
}

and just to note when you did the [...this.state.friends, item ], it only append initial state of friends with new item that user click, thus it does not keep adding to track what user click. If you need the state to keep updated to keep track of what user click. you can do something like this.

add = (item) => {
  const { friendsInComp } = this.state;
  
  this.setState({
    friendsInComp: !friendsInComp ? [...this.state.friends, item ] : [...friendsInComp, item]},
    () => { console.log('this.state.friend', this.state.friendsInComp) }
  )
}

use !friendsInComp if you dont define friendsInComp as empty array inside constructor. otherwise, use friendsInComp.length == 0

hope this help.

Upvotes: 2

Related Questions