обновить параметр в плоском списке в react native

#reactjs #react-native

#reactjs #react-native

Вопрос:

привет, итак, в настоящее время у меня есть 2 экрана, экран A и экран B. На экране A есть плоский список со всеми сообщениями, и когда я нажимаю на конкретное сообщение, я перехожу к экрану B, который содержит подробную информацию об этом сообщении.

На экране B я добавил значок «Нравится», который меняется, когда он заполняется или выделяется, в зависимости от того, понравился ли пост текущему пользователю или нет. Если текущему пользователю понравился пост, запись этого лайка сохраняется в моей базе данных.

Моя проблема в том, что когда пользователю нравится сообщение на экране B, сердце заполняется, но когда я закрываю экран B и перехожу к экрану A, а затем снова к экрану B того же сообщения, сердце по-прежнему выделяется. он меняется на заполненный только при перезагрузке моего приложения.

Экран 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>

)}
 

я не использую контекст или сокращение.

Если кто-нибудь может помочь, вы будете очень признательны. Если требуется больше кода, пожалуйста, скажите мне.

Ответ №1:

вы можете отправлять index и callback post detail отображать

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

используйте функцию обратного вызова для обновления 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
};
 

добавить функцию на первый экран и обновить список

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

Комментарии:

1. это действительно сработало, большое спасибо Мехран. А как насчет likesCount?

2. я обновил свой ответ. если это полезно, отметьте его как правильный.