Building an app and needed to update the data state being rendered in a FlatList. Things were not working as I expected so I broke everything down to a simple example to better understand what was going on.
I feel like I am missing something. I determined from testing in this sample app that Flatlist is looking for an ordered key and has to be exactly ordered starting at 0 and so on...
My question is what am I missing? Is this actually a concrete requirement or do I something configured or coded incorrectly? I have not found any documentation stating this requirement of a very well ordered key.
Here is an example of the issue. If you click on the last item 44, you receive undefined is not an object
as the lookup does not work to the state.
Full code example below;
Post
import React, { Component } from "react";
import { useState } from "react";
import { Button, UIManager, Platform, LayoutAnimation, Modal, Alert, Linking, Pressable, View, Text, StyleSheet, TouchableHighlight, Image, TextInput, FlatList, ActivityIndicator, Dimensions, SafeAreaView, TouchableOpacity, } from "react-native";
import { FlashList } from "@shopify/flash-list";
import { List, ListItem, Avatar } from "react-native-elements";
import { StatusBar } from "expo-status-bar";
import ParsedText from "react-native-parsed-text";
import AntDesign from "react-native-vector-icons/AntDesign";
class Post extends Component {
shouldComponentUpdate(nextProps, nextState) {
const { liked, likeCount } = nextProps;
const { liked: oldLiked, likeCount: oldLikeCount } = this.props;
// If "liked" or "likeCount" is different, then update
return liked !== oldLiked || likeCount !== oldLikeCount;
}
render() {
console.log(this.props.liked);
return (
<View key={this.props.postid} style={styles.container}>
<TouchableOpacity
onPress={() => this.props.onPressLike(this.props.postid)}
>
<AntDesign
name="like2"
size={20}
color={this.props.liked ? "royalblue" : "black"}
/>
</TouchableOpacity>
<Text> {this.props.postid}</Text>
</View>
);
}
}
Home
export default class Home extends Component {
constructor(props) {
super(props);
this.state = {
posts: [
{
postid: "0",
date: "115255668551",
message: "My Post 1 was 4",
uid: "52YgRFw4jWhYL5ulK11slBv7e583xa",
commentCount: "1",
likeCount: "1",
liked: "true",
},
{
postid: "1",
date: "215255668551",
message: "My Post 2",
uid: "52YgRFw4jWhYL5ulK11slBv7e583xb",
commentCount: "1",
likeCount: "1",
liked: "false",
},
{
postid: "2",
date: "315255668551",
message: "My Post 3",
uid: "52YgRFw4jWhYL5ulK11slBv7e583xc",
commentCount: "1",
likeCount: "1",
liked: "true",
},
{
postid: "3",
date: "415255668551",
message: "My Post 4",
uid: "52YgRFw4jWhYL5ulK11slBv7e583xd",
commentCount: "1",
likeCount: "1",
liked: "false",
},
{
postid: "44",
date: "515255668551",
message: "My Post 44 does not work!!!!!!!!!!!!!!!!!",
uid: "52YgRFw4jWhYL5ulK11slBv7e583xe",
commentCount: "1",
likeCount: "1",
liked: "false",
},
],
postsThisIsWorking: [
{
postid: "0",
date: "115255668551",
message: "My Post 0",
uid: "52YgRFw4jWhYL5ulK11slBv7e583xa",
commentCount: "1",
likeCount: "1",
liked: "true",
},
{
postid: "1",
date: "215255668551",
message: "My Post 1",
uid: "52YgRFw4jWhYL5ulK11slBv7e583xb",
commentCount: "1",
likeCount: "1",
liked: "false",
},
{
postid: "2",
date: "315255668551",
message: "My Post 3",
uid: "52YgRFw4jWhYL5ulK11slBv7e583xc",
commentCount: "2",
likeCount: "1",
liked: "true",
},
{
postid: "3",
date: "415255668551",
message: "My Post 3",
uid: "52YgRFw4jWhYL5ulK11slBv7e583xd",
commentCount: "1",
likeCount: "1",
liked: "false",
},
{
postid: "4",
date: "515255668551",
message: "My Post 4",
uid: "52YgRFw4jWhYL5ulK11slBv7e583xe",
commentCount: "1",
likeCount: "1",
liked: "false",
},
],
};
}
renderItem = ({ item, index }) => {
const { date, message, uid, postid, liked } = item;
console.log("---index-----", index);
return (
<Post
postid={postid}
liked={liked}
date={date}
message={message}
uid={uid}
onPressLike={this.handleLikePost}
/>
);
};
handleLikePost = (postid) => {
console.log("----posts----", this.state.posts);
console.log("---postid---", { postid });
let post = this.state.posts[postid]; //error with undefined (evaluating post liked) ----
console.log("----post----", post);
const { liked, likeCount } = post;
const newPost = {
...post,
liked: !liked,
likeCount: liked ? likeCount - 1 : likeCount + 1,
};
this.setState({
posts: {
...this.state.posts,
[postid]: newPost,
},
});
};
render() {
console.log(this.state.posts);
return (
<View style={{ flex: 1 }}>
<FlatList
data={Object.values(this.state.posts)}
renderItem={this.renderItem}
keyExtractor={(item, postid) => postid}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 50,
backgroundColor: "#ecf0f1",
padding: 8,
},
});