kd12345
kd12345

Reputation: 793

update a parameter in a flatlist in react native

hi so i currently have 2 screens screen A and screen B. Screen A has a flatlist with all the posts and when i press on a specific post, i navigate to screen B which is the details of that post.

In Screen B, i have added a like icon that changes when to either filled or outlined depending on whether the current user liked the post or not. If the current user liked a post a record of that like is stored in my database.

My problem is when a user likes a post on Screen B the heart becomes filled but when i close screen B and go to Screen A then to Screen B of the same post again the heart is still outlined. it only changes to filled when i reload my app.

Screen A:

  function PostsScreen({navigation}) {

  const [posts, setPosts] = useState([]);
  const [error, setError] = useState(false);
  const [loading, setLoading] = useState(false);

  const loadPosts = async () => {
  setLoading(true);
  const response = await postsApi.getPosts(); //Api call to get all posts from backend
  setLoading(false);

 if (!response.ok) return setError(true);

 setError(false);
 setPosts(response.data);
 };

useEffect(() => {
loadPosts();
 }, []);

return(
<ActivityIndicator visible={loading} />
<FlatList
  data={posts}
  keyExtractor={(post) => post.id.toString()}
  renderItem={({ item }) => (
    <Card
      title={item.title}
      subTitle={item.subTitle}
      onPress={() => 
      navigation.navigate(routes.POST_DETAILS,item)}
    />
   )}
 />
);
}

ScreenB

function PostDetailsScreen({ route }) {
const post = route.params;
const { user} = useAuth();

const [addedToLikes, setAddedToLikes] = useState(post.isLiked);
const[likesCount,setLikesCount]=useState(post.likesCount)

const addToLikes = (PostId,userId) => {
postsApi.likePost({PostId,userId}); //api call to save like in backend
setAddedToLikes(!addedToLikes);
};

let show_likes="";
if(addedToLikes){
show_likes=(likesCount >1)?(("Liked by you")+" and "+(likesCount - 1)+((likesCount ==2)?( " 
other"):(" others"))):("Liked by you");
}else if(likesCount >0){
show_likes=(likesCount ==1)?(likesCount+ " like"):(likesCount + " likes");
}

return(
<TouchableOpacity onPress={() => {addToLikes(post.id,user.id)}}>
          {addedToLikes?<MaterialCommunityIcons
          name="heart"
        />:<MaterialCommunityIcons
            name="heart-outline"
          />}
</TouchableOpacity>

<View><TextInput>{show_likes}</TextInput></View>

)}

i am not using context or redux.

If anyone can help you'd appreciate it a lot. If anymore code is required please tell me.

Upvotes: 0

Views: 180

Answers (1)

Mehran Khan
Mehran Khan

Reputation: 3636

you can send index and callback to post detail screen

renderItem={({ item,index }) => (
    <Card
      title={item.title}
      subTitle={item.subTitle}
      onPress={() => 
      navigation.navigate(routes.POST_DETAILS,{post:item,index,updateView})}
    />
   )}

use callback function to update list

function PostDetailsScreen({ route }) {
const post = route.params.post;
const index = route.params.index;
const updateView = route.params.updateView;
const { user} = useAuth();

const [addedToLikes, setAddedToLikes] = useState(post.isLiked);
const[likesCount,setLikesCount]=useState(post.likesCount)

const addToLikes = (PostId,userId) => {
postsApi.likePost({PostId,userId}); 
setAddedToLikes(!addedToLikes);
updateView(!addedToLikes,index); // update main view
};

add function on first screen and update list

const updateView = (isLiked, index) => {
  const newPosts = [...posts];
  newPosts[index].isLiked = isLiked;
  let currentCount = newPosts[index].likesCount;
  currentCount = isLiked?currentCount+1:currentCount-1;
  newPosts[index].likesCount = currentCount;
  setPosts(newPosts);
};

Upvotes: 1

Related Questions