Vamos a ver un ejemplo muy simple y básico de cómo proceder a implementar el consumo de una API REST desde React. Este artículo asume que ya se tienen algunos conocimientos básicos de React.
El primer paso consiste en inicializar las variables que necesitaremos para manejar los distintos estados de nuestro componente, para guardar los datos que recibimos de la API y el número de página.
Estas variables las crearemos como variables de estado pero antes vamos a inicializarlas con sus valores predeterminados:
state = {
loading: true,
error: null,
data: {
results:[]
},
nextPage: 1,
};
Este código también puede ir en el constructor.
Los datos los vamos a solicitar a la API en el evento componentDidMount(), es decir, cuando el componente se ha insertado en el DOM. Para esto vamos a llamar a una función fetchData() que también crearemos:
componentDidMount(){
this.fetchData();
}
fetchData = async () => {
this.setState({ loading: true, error: null });
try {
const response =
await fetch(${url}?page=${nextPage});
const data await response.json();
this.setState({
data: { results: [].concat(this.state.data.results, data.results) },
loading: false,
nextPage: this.state.nextPage + 1
});
}
catch(error){
this.setState({loading: false, error: error});
}
}
La función fetchData es asíncrona porque a su vez llama a métodos asíncronos, como es fetch. Por eso la debemos declarar con la palabra clave async.
En la función empezamos asignando el estado de loading en true ya que queremos indicar que estamos realizando la carga de datos desde la API. Luego utilizaremos esta variable para mostrar un mensaje de “loading” o también se puede emplear una animación. La variable de estado error la asignamos en null porque no tenemos ningún error de carga.
Dentro de un bloque try llamamos a la función fetch, la cual es asíncrona, por eso debemos llamarla con la palabra clave await. El método fetch es el que realiza la petición a la API y recibe, como argumento, la URL hacia donde debemos enviar la petición. El resultado de esta petición lo guardamos en la variable response.
Para obtener los datos a partir de la variable response llamamos a otra función asíncrona que es json().
Los datos obtenidos los guardaremos en la variable de estado data, mediante el método setState(). En nuestro ejemplo, el array con los resultados son un objeto results dentro de data.
Para ir sumando los datos que obtenemos en sucesivas paginaciones utilizamos el método concat() y vamos agregando estos resultados a this.state.data.results.
Render
El listado de los resultados es muy sencillo. Lo haremos en la función render(). Para esto utilizaremos map():
<ul>
{this.state.data.results.map(character => (
<li key={character.id}>{character.name}</li>
))}
</ul>
En el método render también vamos a mostrar el texto (o animación) para el estado “loading” y el mensaje de error, si existiese:
{this.state.loading && (
<div>Loading...</div>
)}
if (this.state.error) {
return (
<div>An error has occurred: {this.state.error.message}</div>
)}
Por último, no debemos de olvidarnos del botón para cargar los resultados de las siguientes páginas. Este será un botón que solo se mostrará cuando this.state.loading sea false y llamará a la función fetchData() en su evento onClick:
{!this.state.loading && (
<button onClick={() => this.fetchData()}>Load more</button>
)}