yo lo resolvà de la siguiente forma:
static instance = new Storage();
Introducción a React Native
Qué aprenderás sobre React Native y el proyecto que harás
Instalación React Native CLI en Windows
Instalación React Native CLI en MacOS
Estructura de un proyecto en react native
Configuración de la navegación en react native
Nuestra primera pantalla con Stack Navigator
Iniciando el desarrollo de nuestra aplicación
Navegación entre pantallas
Usando una REST API con fetch
Crear nuestra primera lista con FlatList
Dando estilos a nuestra FlatList
Pasar información entre pantallas
Creando nuestra vista detalle
Creando una FlatList horizontal
Elementos avanzados
Buscador con TextInput
Agregando tabs de navegación
Creando nuestra sección de favoritos
Creando nuestra librerÃa de storage
Agregando favoritos
Eliminando favoritos
Lista de favoritos
Cierre
MentorÃa Expert
Modelos mentales y buenas prácticas con React.js
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Aportes 12
Preguntas 3
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
}
});
Los aportes, preguntas y respuestas son vitales para aprender en comunidad. RegÃstrate o inicia sesión para participar.