Simplemente en la funcion onReloadCheckFavorite puede llamar al estado y negarlo, creo que esta forma es mas intuitiva.
const onReloadCheckFavorite = () => {
setReloadCheck(!reloadCheck);
}
Sistema de formularios
Descarga el código base del proyecto
Pantalla de Mi cuenta
Formulario de Login
Sistema de formularios avanzados
Implementando Formik y Yup
Iniciando sesión
useAuth: manejo de sesiones con Custom Hooks y React Context
Datos del usuario y logout
Sistema de favoritos
Botón de añadir a favoritos
Almacenando un Pokémon favorito con AsyncStorage
Almacenando varios Pokémon favoritos
Pantalla de favoritos
Toggle en el botón de favoritos
Eliminar Pokémon de favoritos
Lista de Pokémon favoritos
Navegación hacia atrás en favoritos
Logout
Sincronizando información entre pantallas
Pre deploy
Configuración básica antes del BUILD
Cómo generar el APK y AAB para Android
Cómo generar la app para iOS
¿Quieres cursos más avanzados de React Native?
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
No se trata de lo que quieres comprar, sino de quién quieres ser. Aprovecha el precio especial.
Antes: $249
Paga en 4 cuotas sin intereses
Termina en:
Agustín Navarro Galdon
Aportes 7
Preguntas 1
Simplemente en la funcion onReloadCheckFavorite puede llamar al estado y negarlo, creo que esta forma es mas intuitiva.
const onReloadCheckFavorite = () => {
setReloadCheck(!reloadCheck);
}
Otra alternativa, podría ser en la misma función para sumar a los favoritos, negar al estado inicial de si es favorito o no (en mi caso isFavorites):
const addFavorites = async () => {
try {
await addFavorite(id);
setIsFavorites(!isFavorites)
} catch (err) {
console.log(err)
}
};
Mi código, el que creo que es más simplificado al del profesor y sin usar lodash:
FavButton.jsx:
import { useState, useLayoutEffect } from 'react'
import PropsTypes from 'prop-types'
import Icon from 'react-native-vector-icons/FontAwesome5'
import { addFavoritePokemon, removeFavoritePokemon, getFavoritePokemons } from '../../api/favStorage'
const FavButton = ({ id }) => {
const [ fav, setFav ] = useState(undefined)
useLayoutEffect(() => {
(async () => {
const favorites = await getFavoritePokemons()
const isFav = favorites.includes(id)
setFav(isFav)
})()
}, [])
const handleFavorite = () => {
fav
? removeFavoritePokemon(id)
: addFavoritePokemon(id)
setFav(!fav)
}
return (
<Icon
name='heart'
solid={fav && true}
color="#000"
size={24}
style={{ marginRight: 20 }}
onPress={handleFavorite}
/>
)
}
FavButton.propTypes = {
id: PropsTypes.number.isRequired
}
export default FavButton
favStorage.js
import AsyncStorage from '@react-native-async-storage/async-storage'
export const addFavoritePokemon = async (id) => {
try {
const favorites = await getFavoritePokemons()
favorites.push(id)
await AsyncStorage.setItem('favorites', JSON.stringify(favorites))
} catch (error) {
console.log(error)
}
}
export const removeFavoritePokemon = async (id) => {
try {
const favorites = await getFavoritePokemons()
const filterFavorites = favorites.filter(fav => fav !== id)
await AsyncStorage.setItem('favorites', JSON.stringify(filterFavorites))
} catch (error) {
console.log(error)
}
}
export const getFavoritePokemons = async () => {
try {
const response = await AsyncStorage.getItem('favorites')
return response != null ? JSON.parse(response) : []
} catch (error) {
console.log(error)
}
}
favorites: {
async getFavorites() {
try {
const response = await AsyncStorage.getItem(POKEMON_FAV_STORAGE);
if (response) {
let result = JSON.parse(response).filter(
(item, index) => JSON.parse(response).indexOf(item) === index
);
return result;
} else return [];
} catch (error) {
throw new Error(error);
}
},
async deleteFavorites(id) {
try {
const favorites = await this.getFavorites();
const filteredItems = favorites.filter((item) => item !== id);
await AsyncStorage.setItem(POKEMON_FAV_STORAGE, JSON.stringify(filteredItems));
return filteredItems;
} catch (error) {
throw new Error(error);
}
},
async addToFavorites(id) {
try {
const favorites = await this.getFavorites();
favorites.push(id);
await AsyncStorage.setItem(POKEMON_FAV_STORAGE, JSON.stringify(favorites));
return { message: 'Agregado correctamente a favoritos' };
} catch (error) {
throw new Error(error);
}
},
},
Con el onpress y dirigiéndolo a la función de cada caso se puede hacer esto sin necesidad de crear mas funciones, faltaría la lógica de borrarlo de la base de datos que seguramente es en las próximas clases
const addFavorites = async () => {
await addPokemonFavorite(id);
setIsFavorite(true);
};
const removeFavorites = () => {
console.log("eliminando");
setIsFavorite(false);
};
onPress={isFavorite ? removeFavorites : addFavorites}
Lo que yo hice fue modificar la función de addPokemonFavorite y verificar si existía el ID en los favoritos, si existe pues lo saco, sino le hago push y hago set del storage, así:
export async function addPokemonFavorite(id) {
try {
const favorites = await getFavorites();
favorites.includes(id) ? favorites.splice(favorites.indexOf(id), 1) : favorites.push(id);
await AsyncStorage.setItem(FAVORITES_STORAGE, JSON.stringify(favorites));
} catch (error) {
throw error;
}
}
Y en el botón de favorito lo que hice fue una función que chequea al ingresar si el pokemon es un favorito y luego setearlo
const Favorite = ({ id }) => {
const [isFav, setIsFav] = useState(false);
const addFavorite = async () => {
await addPokemonFavorite(id);
await isFavorite(id);
};
const isFavorite = async () => {
const isFavourite = await isPokemonFavorite(id);
setIsFav(isFavourite);
};
useEffect(() => {
isFavorite(id);
}, [id]);
return (
<>
<Icon
name='heart'
color='#FFF'
size={25}
onPress={addFavorite}
style={{ marginRight: 20 }}
solid={isFav}
/>
</>
);
};
export default Favorite;
Creo que el componente Favorite puede ser hecho de una mejor manera, pero está es bastante legible
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?