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

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

14 Días
16 Hrs
27 Min
5 Seg

Toggle en el botón de favoritos

12/21
Recursos

Aportes 7

Preguntas 1

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

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

Creo que se complejizo mucho el código, este es mi servicio

 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}
Hay una opción muy sencilla que es usar props drilling, sube el estado \[isFavorite y setIsFavorite] de orden al compente padre y le agregas otra dependencia al useEffect, luego si quieres optimizar renderizado usas memo en los demás componentes, para que no sea afecten, la otra es añadir los favoritos a un contexto y agregar a la dependencia los favoritos, cuando cambien tendrá que renderizar nuevamente.

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