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

Crear nuestra primera lista con FlatList

9/22
Recursos

Aportes 18

Preguntas 5

Ordenar por:

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

Les comparto un custom hook equivalente a lo realizado en esta clase:

import {useState, useEffect} from 'react';
import Http from '../lib/http';

const useCoins = () => {
    const [coins, setCoins] = useState([]);
    useEffect(() => {
        (async () => {
            const response = await Http.instance.get(
                'https://api.coinlore.net/api/tickers/',
            );
            setCoins(response.data);
        })();
    }, []);
    return [coins];
};

export default useCoins;

Hola Devs:
-El curso se hace mas sencillo cuando tienes bases de ReactJS y sobre todo JavaScript (ECMAScript 6+), aqui les tengo mi avance usando componentes funcionales y custom hooks.

-Repositorio: Crypto-Tracker
Recuerda, #NuncaParesDeAprender 💚

Pffft increíble, comparado con Xamarin (que es una tecnología genial) es super rápido poder crear un ListView

CoinsScreen usando componentes funcionales y hooks

const CoinsScreen = (props) => {
  const [coins, setcoins] = useState({});
  const [loading, setloading] = useState(false);
  const getData = async () => {
    setloading(true);
    let res = await gethttps('tickers');
    setcoins(res.data);
    setloading(false);
  };

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

  return (
    <>
      <View style={style.container}>
        {loading ? (
          <ActivityIndicator style={style.loader} color="white" size="large" />
        ) : null}
        <FlatList
          data={coins}
          renderItem={({item}) => <CoinsItem item={item} />}
        />
      </View>
    </>
  );
};

export default CoinsScreen;

Creo que es una mala practica el asignar el estado directamente en el componentDidMount, seria mejor crear una función que lo gestione y sea llamada en ese componentDidMount

componentDidMount = async () => { const res = await Http.instance.get( 'https://api.coinlore.net/api/tickers/', ); const {data = {}} = {...res}; this.setCoinsData(data); }; setCoinsData = (data) => { this.setState({coins: data}); };

import React from 'react'
import { View, StyleSheet, FlatList, ActivityIndicator } from 'react-native'
import { useGetCoins } from '../../lib/hooks'
import { CoinsItem } from './CoinsItem'

const URL_COINS = 'https://api.coinlore.net/api/tickers/'
export function CoinsScreen ({ navigation }) {
  const { coins } = useGetCoins({ url: URL_COINS })
  return (
    <View style={styles.container}>
      {
        coins.length
          ? <FlatList
              data={coins}
              renderItem={CoinsItem}
            />
          : <ActivityIndicator
              color='#fff'
              size='large'
            />
      }
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'red'
  },
  titleText: {
    color: '#fff',
    textAlign: 'center'
  },
  btn: {
    padding: 8,
    backgroundColor: 'blue',
    borderRadius: 8,
    margin: 16
  },
  btnText: {
    color: '#fff',
    textAlign: 'center'
  }
}
)

Les comparte dos formas de implementar el loading:

{loading && <ActivityIndicator color="#3b3b3b" style={styles.loader} size="large"/>}
      {<FlatList data={coins} renderItem={({ item }) => <CoinItem {...item} />} />}
{loading ? (
        <ActivityIndicator color="#3b3b3b" style={styles.loader} size="large" />
      ) : (
        <FlatList data={coins} renderItem={({ item }) => <CoinItem {...item} />} />
      )}

Si quieren centrar el Spinner intenta esto:

<View style={styles.loaderContainer}>
    <ActivityIndicator color="#3b3b3b" size="large" />
</View>
loaderContainer: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },

Codigo de la aplicacion hasta esta clase: https://github.com/civilian/cryptoTracker/tree/af780eeec81fbcf60e17a0c336417019af17ded5 (Con un patch que me toco aplicar para que funcionara en windows. Algo que tiene que ver con “Correct error EISDIR: illegal operation on a directory”)

tuve algunos errores y me tarde como dos dias, pero se logro el reto

Hola a todos por si acaso aquí lo tengo con hook : https://github.com/eddypv/crytoTracker

Tuve un problema al enviarle el arreglo coins como data al FlatList y era porque en coins no venia el arreglo directamente, tuve que enviarle data={coins.data}

Se pueden utilizar hooks en react-native?

A pesar de que es una api pública si bajo el rendimiento el hecho de pasar los datos por el CoinsItem.

Si de pronto les da un error molesto en la consola donde corre metro, sobre los key de los items de la lista, yo lo solucionés asì:

<FlatList
          data={coins}
          keyExtractor={(item) => item.id}
          renderItem={({item}) => (
            <CoinsItem item={item} />
          )}
        />```

En los estilos veo que no ocupas “px”, “vw”, “%”, etc. Qué tipo de medida es?

En windows si no pueden entrar al comand + m para el debug escriban esto en la consola donde arrancaron el android

adb shell input keyevent 82

Cree un custom hook para obtener loas coinst:

import {useState, useEffect} from 'react';
import Http from '../../../libs/Http';
import {HttpStatus} from '../../../libs/HttpStatus';

export const useCoins = () => {
  const url = 'https://api.coinlore.net/api/tickers/';
  const [coins, setCoins] = useState();
  const [requestStatus, setRequestStatus] = useState(null);

  useEffect(() => {
    (async () => {
      const httpStatus = new HttpStatus();

      try {
        setRequestStatus(httpStatus.onLoading());

        const {data: coinsList} = await Http.instance.get(url);

        if (coinsList.length === 0) {
          setRequestStatus(httpStatus.onEmpty());
          return;
        }

        setCoins(coinsList);
        setRequestStatus(httpStatus.onSuccess());
      } catch (err) {
        setRequestStatus(httpStatus.onError());
      }
    })();
  }, []);

  return [coins, requestStatus];
};

Cree una clase para manejar el estado del request:

export class HttpStatus {
  empty: boolean;
  error: boolean;
  loading: boolean;
  success: boolean;

  constructor() {
    this.empty = false;
    this.error = false;
    this.loading = false;
    this.success = false;
  }

  onInit() {
    return {
      empty: false,
      error: false,
      loading: false,
      success: false,
    };
  }

  onError() {
    return {
      empty: false,
      error: true,
      loading: false,
      success: false,
    };
  }

  onEmpty() {
    return {
      empty: true,
      error: false,
      loading: false,
      success: false,
    };
  }

  onLoading() {
    return {
      empty: false,
      error: false,
      loading: true,
      success: false,
    };
  }

  onSuccess() {
    return {
      empty: false,
      error: false,
      loading: false,
      success: true,
    };
  }
}

Y así lo uso en la página:

const CoinsPage = () => {
  const [coins, requestStatus] = useCoins();

  return (
    <View style={styles.container}>
      {requestStatus?.loading && <ActivityIndicator style={styles.indicator} color="#000" size="large" />}
      {requestStatus?.success && <FlatList data={coins} renderItem={({item}) => <ItemCoins />} />}
      {requestStatus?.error && <Text>{'error'}</Text>}
    </View>
  );
};