i'm trying to show a text whenever i remove item from favourites but instead the condition eliminates every item i render . I used conditional rendering for doing that and i realized i replaced all the items and not the single item i want to eliminate.
import React, { useEffect, useRef, useState } from 'react'
import { View, StyleSheet, Text, Image } from 'react-native'
import { FavouriteStackParams, Movie, NavigationProps } from '../types'
import { FlatList } from 'react-native-gesture-handler'
import { MaterialCommunityIcons } from '@expo/vector-icons'
import { StorageResources } from '../api'
import LoaderBox from './LoaderBox'
import navigation from '../navigation'
import { useFocusEffect } from '@react-navigation/native'
export default function FavouriteBox() {
const [favoritesFilm, setFavorite] = useState<Movie[]>([])
const [isLoadingFav, setIsLoadingFav] = useState(true)
const [titleText, setTitleText] = useState(false)
useFocusEffect(
React.useCallback(() => {
setIsLoadingFav(true)
getFav()
return () => {
}
}, [navigation])
)
async function removeMovie(id: Movie) {
const value = await StorageResources.storageGet('favmovies')
const alteredValue = value.filter(function (e: { id: any }) {
return e.id !== id
})
StorageResources.storageSave('favmovies', alteredValue)
setTitleText(true)
}
async function getFav() {
const favorites = await StorageResources.storageGet('favmovies')
setFavorite(favorites)
setIsLoadingFav(false)
setTitleText(false)
}
const renderItemFav = ({ item }: any) => (
<FavMovie name={item.name} title={item.title} poster_path={item.poster_path} id={item.id} />
)
const FavMovie = ({ title, poster_path, name, id }: any) => (
<View style={styles.wrap}>
{titleText && <Text style={styles.text}>Removed from favorites</Text>}
{!titleText && (
<>
<Image
style={styles.image}
source={{
uri: `https://image.tmdb.org/t/p/w500/${poster_path}`,
}}
/>
<Text style={styles.fav}>{title}</Text>
<Text style={styles.fav}>{name}</Text>
<MaterialCommunityIcons
onPress={() => {
removeMovie(id)
}}
name="bookmark-minus-outline"
style={styles.book}
/>
</>
)}
</View>
)
if it possible i want to create a condition that show a text " removed from favorites" only for item that had been eliminated but how can i do it?
CodePudding user response:
To make your fav movies state unique, add a new property to favMovies called isDeleted so the object will be in this format.
{ title, poster_path, name, id, isDeleted: false }
Then in your removeMovie function, you will need to update your state depending on whether the movie is deleted or not.
function removeMovie(id) {
const alteredValue = favoritesFilm.map(film => {
if (film.id == id) {
return { ...film, isDeleted: true }
}
return film;
})
setFavorites(alteredValue);
}
Notice how we did not set the data in the storage yet, this is because in your current logic, you are getting a fresh set of favmovies from your storage every time you remove a movie but this is redundant because you have already set the favorite film state with the movies from the storage at the beginning in your useFocusEffect. Instead we will update the state with the movie that was deleted.
Then in your FavMovie component, update your code so that it takes in the movie isDeleted state, we will then use that state to conditonally render your text.
const FavMovie = ({ title, poster_path, name, id, isDeleted }: any) => (
<View style={styles.wrap}>
{isDeleted && <Text style={styles.text}>Removed from favorites</Text>}
{!isDeleted && (
...
And update your rendering function to take in the state:
const renderItemFav = ({ item }: any) => (
<FavMovie name={item.name} title={item.title} poster_path={item.poster_path} id={item.id} isDeleted={item.isDeleted} />
)
Finally to update your storage, in your useFocusEffect function, there is a return function that will trigger whenever you leave the screen, we can make use of that function to update the storage with the updated films.
return async () => {
const updatedFilm = favoritesFilm.filter(film => film.isDeleted !== true)
StorageResources.storageSave('favmovies', updatedFilm)
}