1

Agregando botón de favoritos en header

Vamos a agregar nuestro botón de favoritos, este lo vamos a agregar dentro de la pantalla de detalle y en la barra superior de navegación, del lado derecho.

Se contara con dos imágenes dentro de un Pressable el cual ira alternando de imagen dependiendo del estado que se encuentre (favorito agregado o no).

Quedando mas o menos de la siguiente forma

FavAgregado.png

Favorito Agregado

FavNoAgregado.png

Favorito No Agregado

Preparando el componente

Primero vamos a crear el componente donde tendremos nuestra estrella, para comenzar agregaremos los componentes basicos y un estilo basico

//FavoriteButton.js
import React, {useState} from 'react';
import {Pressable, View, StyleSheet, Image} from 'react-native';


const FavoriteButton = () => {
	const [isFavorite, setIsFavorite] = useState(false);
	
	const handlePress = () => {
    setIsFavorite(!isFavorite);
  };

	return (
    <View>
      <Pressable style={styles.button} onPress={() => handlePress()}>
        {isFavorite ? (
          <Image
            source={require('../../assets/ActiveStar.png')}
            style={styles.star}
          />
        ) : (
          <Image
            source={require('../../assets/InactiveStar.png')}
            style={styles.star}
          />
        )}
      </Pressable>
    </View>
  );
};

const styles = StyleSheet.create({
  button: {
    marginRight: 8,
  },
});

export default FavoriteButton;

Como se puede observar, simplemente creamos un Pressable donde colocamos una imagen dependiendo de una variable que cambiara de valor cuando el botón sea presionado.

De esta manera si probamos el componente en cualquier parte nos daremos cuenta que ya cambia de estado cuando lo accionamos, intercambiando la imagen entre la estrella activa y la inactiva.

No es necesario colocar una estrella, también podemos colocar un corazón o cualquier par de imágenes que deseemos, recomiendo que las imágenes sean de 35x35, pero puedes usar el tamaño que desees.

Colocando el componente en nuestro header

Para colocar nuestro componente dentro del header vamos a aprovechar las props que tiene nuestro Stack Navigator, especificamente la propiedad llamada headerRight, esta nos permite, como su nombre lo indica, colocar algun componente de nuestro gusto, como un menu despegable en la parte derecha de nuestro header.

Siguiendo el mismo procedimiento que utilizamos para modificar el titulo de nuestro header, colocaremos nuestro componente de la siguiente forma:

//CoinDetailScreen.jsimport FavoriteButton from './FavoriteButton';

const CoinDetailScreen = ({route, navigation}) => {
	/*
	*
	*
	*/
useEffect(() => {
    navigation.setOptions({
      title: coin.symbol,
      headerRight: () => <FavoriteButton coin={coin} />,
    });
    getMarkets(coin.id);
  }, []);

	return (
		/*
		*
		*/
	)
}

Simplemente colocamos la propiedad, y esta recibe un componente, aquí importamos nuestro componente y lo ponemos en nuestra propiedad headerRight, también le pasamos por parámetro la información de nuestra moneda actual pues la necesitaremos para verificar el estado después.

Verificando si nuestra moneda esta en favoritos

Una vez colocada, debemos manejar el estado para agregar y remover la moneda seleccionada de favoritos. De igual forma cuando entremos a la pantalla de detalle, nuestro componente debe reflejar si la moneda se encuentra agregada o no a favoritos

Para esto agregaremos las siguientes funciones a nuestro componente:

//FavoriteButton.jsimport React, {useEffect, useState} from'react';import {Pressable, View, StyleSheet, Image} from'react-native';import Storage from'../../libs/storage';const FavoriteButton = ({coin}) => {
  const [isFavorite, setIsFavorite] = useState(false);

  const handlePress = () => {
    if (isFavorite) {
      removeFavorite();
    } else {
      addFavorite();
    }
  };

  const checkFavorite = async () => {
    const key = `favorite-${coin.id}`;
    const checking = await Storage.instance.get(key);

    //if its in favorite, showing the starif (checking !== null) {
      setIsFavorite(true);
    }
  };

const addFavorite = async () => {
    const key = `favorite-${coin.id}`;
    const stored = await Storage.instance.store(key, JSON.stringify(coin));

    if (stored) {
      setIsFavorite(true);
    }
  };

  const removeFavorite = async () => {
    const key = `favorite-${coin.id}`;
    const deleted = await Storage.instance.remove(key);

    if (deleted) {
      setIsFavorite(false);
    }
  };

  useEffect(() => {
    checkFavorite();
  }, [isFavorite]);

  return (
    /*
		*
		*
		*/
  );
};

const styles = StyleSheet.create({
  button: {
    marginRight: 8,
  },
});

exportdefault FavoriteButton;

Se puede observar que agregamos 3 funciones, checkFavorite, addFavorite y removeFavorite.

En el caso de checkFavorite, esta se encuentra dentro de useEffect, significando que se ejecutara cada vez que el componente se monte y cada vez que isFavorite sea actualizado. De esta manera logramos que cada vez que entremos a una moneda, se vea reflejado si esta agregada a favoritos o no.

En pocas palabras, esta función revisa si la moneda esta guardada en nuestro storage, si es así, actualizara el valor de isFavorite, de otra manera, lo mantendrá por defecto, como false.

Para addFavorite y removeFavorite, estas funciones introducen o remueven la moneda de nuestro asyncStorage, así como actualizar el valor de isFavorite para que nuestro componente cambie de estado.

Por ultimo, actualizamos handlePress para que mande a llamar a nuestras funciones para agregar o remover favoritos dependiendo del valor de isFavorite.

Y listo, así tenemos un botón de favoritos funcional dentro de nuestro header.

Escribe tu comentario
+ 2