No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Curso de React Native CLI

Curso de React Native CLI

Alejandro Sanabria

Alejandro Sanabria

Agregando favoritos

18/22
Recursos

Aportes 12

Preguntas 3

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Regístrate o inicia sesión para participar.

yo lo resolví de la siguiente forma:

static instance = new Storage();

colors


const colors = {
  blackPearl: "#20252c",
  charade: "#272c35",
  zircon: "#3a4049",
  picton: "#3c6fc8",
  carmine: "#ef6372",
  white: "#fff"
};


``

En el archivo storage.js falta exportar la clase Storage, para ello agregar:
expost default Sotrage
Además agregar el new en
static instance = new Storage()

estilos de los botones favoritos


  btnFavorite: {
    padding: 8,
    borderRadius: 8
  },
  btnFavoriteText: {
    color: Colors.white
  },
  btnFavoriteAdd: {
    backgroundColor: Colors.picton
  },
  btnFavoriteRemove: {
    backgroundColor: Colors.carmine
  }

Recomiendo utilizar fliper, te permite hacer un debug mas rápido que el chrome, analizar las peticiones a la api; loq ue envias y lo que regresa, tiene muchos plugins como para trabajar con redux, con local storage y tambien peudes ver lo que hay en async storage, realmente una herrmienta muy completa.

Toggle se escribe con doble g y una sola o.

Para quienes quieran iconos SVG les recomiendo la siguiente página: https://www.npmjs.com/package/react-native-svg-icon

Si tienen problemas con el modulo de async-storage, priumero se debió instalar

npm install @react-native-async-storage/async-storage 

porque el que el profe da ya no funciona, por otra parte en el storage.js se debe importar de la siguiente manera

import AsyncStorage from '@react-native-async-storage/async-storage';

y por ultimo algo que no se hace en la clase anterior es agregar el new a la instancia:

static instance = new Storage();

y exportar la clase al final

export default Storage;

si siguen presentando el error, deben eliminar la dependencia el cache y volverlo a instalar

Asi queda el titulo alineado con el botón agregando el ‘alignItems:center’

subHeader: {
    backgroundColor: 'rgba(0,0,0, 0.2)',
    padding: 16,
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
  },

como puedo arreglar este error?

 TypeError: undefined is not an object (evaluating '_storage.default.instance.store')```

No pude configurarlo con la librería de comunity storage, por lo cual lo hice con firebase. Dejo las funciones para agregar y borrar por si alguno se anima.

Aclaro que deben realizar la configuración de firebase, usando:

npm i --save firebase

Luego crean la referencia al documento que van a crear en firebase

  const coins = db.collection("currencies");

Acto seguido crean las funciones, agregar, remover y toggle

 const addfavoriteCoin = async () => {
    await coins
      .doc(coin.name)
      .set({
        coin: coin.name,
      })
      .then(setIsFavorite(true));
  };

  const removeFavoriteCoin = async () => {
    await await coins.doc(coin.name).delete()
      .then(setIsFavorite(false));
  };

  const toggleFavorite = () => {
    if (isFavorite) {
      removeFavoriteCoin();
    } else {
      addfavoriteCoin();
    }
  };

Ahora como es necesario tomar los datos al renderizar para cambiar el estado del botón, agregamos el siguiente código antes de return del componente (junto con las otras funciones)

 const getData = async () => {
    let a = await coins.where("coin", "==", coin.name).get();
    if (a.empty) {
      setIsFavorite(false);
      return;
    }

    a.forEach((doc) => {
      setIsFavorite(true);    
    });
  };

 useEffect(() => {    
    getData(); 
  }, []);

Para los que usan componentes de clases, getData lo ponen en componentDidMount

Comparto mi código de CoinDetailScreen 😃
Excelente clase!

import  React, {Component } from 'react';
import {View, Image, Text, StyleSheet, SectionList,Pressable} from 'react-native'
import Colors from '../../res/color'
import Http from '../../libs/http'
import CoinMarketItem from '../coinDetail/CoinMarketItem'
import Storage from '../../libs/storage'

import { FlatList } from 'react-native-gesture-handler';

class CoinDetailScreen extends Component {

    state = {
        coin:{},
        markets:[],
        isFavorite:false,
    }

    toggleFavorite = () =>{
      if(this.state.isFavorite){
        this.removeFavorite()
      }else{
        this.addFavorite()
      }
    }

    addFavorite = () => {
      const coin = JSON.stringify(this.state.coin)
      const key = `favorite-${this.state.coin.id}`

      const stored = Storage.instance.store(key,coin)

      if(stored){
        this.setState({isFavorite:true})
      }
    }
    removeFavorite = () => {

    }
    getSymbolIcon = (name) => {
        if (name) {
            const symbol = name.toLowerCase().replace(" ","-")
          return `https://c1.coinlore.com/img/16x16/${symbol}.png`;
        }
    };
    getSections = (coin) => {

        const sections = [
          {
            title: "Market cap",
            data: [coin.market_cap_usd]
          },
          {
            title: "Volume 24h",
            data: [coin.volume24]
          },
          {
            title: "Change 24h",
            data: [coin.percent_change_24h]
          }
        ];
    
        return sections;
    }

    getMarkets = async (coinId) => {

      const url = `https://api.coinlore.net/api/coin/markets/?id=${coinId}`
  
      const markets = await Http.instance.get(url);
  
      this.setState({ markets });
    }

    componentDidMount() {
        const {coin} = this.props.route.params;
        this.props.navigation.setOptions({title: coin.symbol})
        this.getMarkets(coin.id)
        this.setState({coin})
    } 

    render(){
        const {coin,markets,isFavorite} = this.state;
        return(
            <View style={styles.container}>
                <View style={styles.subHeader}>
                  <View >
                    <Image style={styles.iconImg} source={{uri: this.getSymbolIcon(coin.name)}}></Image>
                    <Text style={styles.titleText}>
                        {coin.name}
                    </Text>
                  </View>
                    
                    <Pressable
                    onPress={this.toggleFavorite}
                    style={[
                      styles.btnFavorite,
                      isFavorite?
                      styles.btnFavoriteRemove :
                      styles.btnFavoriteAdd
                    ]}>
                      <Text style={styles.btnFavoriteText}>
                        {isFavorite ? "Eliminar favorito":"Agregar favorito"}
                      </Text>
                    </Pressable>
                </View >
                <SectionList 
                    style={styles.section}
                    sections={this.getSections(coin)} 
                    keyExtractor={(item,index) => item+index} 
                    renderItem={({item}) => 
                    <View style={styles.sectionItem}>
                        <Text style={styles.itemText}>{item}</Text>
                    </View>
                    } 
                    renderSectionHeader={({section: {title}}) =>
                    <View style={styles.sectionHeader}> 
                        <Text style={styles.sectionText}>{title}</Text>
                    </View>
                    } 
                    />
                    <Text style={styles.marketsTitle}>Markets</Text>

                    <FlatList
                      style={styles.list}
                      horizontal={true}
                      data={markets}
                      renderItem={({ item }) => <CoinMarketItem item={item} />}
                    />
            </View>
        )
    }
}
export default CoinDetailScreen

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: Colors.charade
  },
  row: {
    flexDirection: "row"
  },
  subHeader: {
    backgroundColor: "rgba(0, 0, 0, 0.1)",
    padding: 16,
    flexDirection: "row",
    justifyContent: "space-between"
  },
  titleText: {
    fontSize: 16,
    fontWeight: "bold",
    color: "#fff",
    marginLeft: 8
  },
  iconImg: {
    width: 25,
    height: 25
  },
  section: {
    maxHeight: 220
  },
  list: {
    maxHeight: 100,
    paddingLeft: 16
  },
  sectionHeader: {
    backgroundColor: "rgba(0,0,0, 0.2)",
    padding: 8
  },
  sectionItem: {
    padding: 8
  },
  itemText: {
    color: Colors.white,
    fontSize: 14
  },
  sectionText: {
    color: Colors.white,
    fontSize: 14,
    fontWeight: "bold"
  },
  marketsTitle: {
    color: Colors.white,
    fontSize: 16,
    fontWeight: "bold",
    marginBottom: 16,
    marginLeft: 16
  },
  btnFavorite: {
    padding: 8,
    borderRadius: 8
  },
  btnFavoriteText: {
    color: Colors.white
  },
  btnFavoriteAdd: {
    backgroundColor: Colors.picton
  },
  btnFavoriteRemove: {
    backgroundColor: Colors.carmine
  }
});