#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. я обновил свой ответ. если это полезно, отметьте его как правильный.