
Datos en React con Fetch API y axios

Si es nuevo en React y quizás solo haya jugado con la creación de aplicaciones de tareas pendientes y contadores, es posible que aún no se haya encontrado con la necesidad de obtener datos para su aplicación. Probablemente llegará un momento en el que necesitarás hacer esto, ya que las aplicaciones React son más adecuadas para situaciones en las que manejas tanto datos como estado.
El primer conjunto de datos que quizás necesites manejar puede estar codificado en tu aplicación React, como lo hicimos para esta demostración de nuestro tutorial sobre límites de error:
¿Qué pasa si quieres manejar datos desde una API? Ese es el propósito de este tutorial. Específicamente, usaremos la API Fetch y axios como ejemplos de cómo solicitar y usar datos.
La API de recuperación
La API Fetch proporciona una interfaz para recuperar recursos. Lo usaremos para obtener datos de una API de terceros y veremos cómo usarlo al obtener datos de una API creada internamente.
Usar Fetch con una API de terceros
Buscaremos usuarios aleatorios de JSONPlaceholder, una API REST falsa en línea para realizar pruebas. Comenzamos a crear nuestro componente y declarando algún estado predeterminado.
class App extends React.Component { state = { isLoading: true, users: [], error: null } render() { React.Fragment /React.Fragment }}
Es probable que haya un retraso cuando la red solicita datos. Podrían ser unos segundos o tal vez unos milisegundos. De cualquier manera, durante este retraso, es una buena práctica informar a los usuarios que algo está sucediendo mientras se procesa la solicitud.
Para ello utilizaremos isLoading
para mostrar el mensaje de carga o los datos solicitados. Los datos se mostrarán cuando isLoading
sea false
, de lo contrario se mostrará un mensaje de carga en la pantalla. Entonces el render()
método se verá así:
render() { const { isLoading, users, error } = this.state; return ( React.Fragment h1Random User/h1 // Display a message if we encounter an error {error ? p{error.message}/p : null} // Here's our data check {!isLoading ? ( users.map(user = { const { username, name, email } = user; return ( div key={username} pName: {name}/p pEmail Address: {email}/p hr / /div ); }) // If there is a delay in data, let's let the user know it's loading ) : ( h3Loading.../h3 )} /React.Fragment );}
El código básicamente hace esto:
- Se desestructura
isLoading
yusers
desdeerror
el estado de la aplicación no tenemos que seguir escribiendothis.state
. - Imprime un mensaje si la aplicación encuentra un error al establecer una conexión
- Comprueba si se están cargando datos
- Si la carga no ocurre, entonces debemos tener los datos, por lo que los mostramos
- Si se está cargando, entonces aún debemos estar trabajando en ello y mostrar “Cargando…” mientras la aplicación está funcionando.
Para que los pasos 3 a 5 funcionen, debemos realizar la solicitud para obtener datos de una API. Aquí es donde la API JSONplaceholder será útil para nuestro ejemplo.
fetchUsers() { // Where we're fetching data from fetch(`https://jsonplaceholder.typicode.com/users`) // We get the API response and receive data in JSON format... .then(response = response.json()) // ...then we update the users state .then(data = this.setState({ users: data, isLoading: false, }) ) // Catch any errors we hit and update the app .catch(error = this.setState({ error, isLoading: false }));}
Creamos un método llamado fetchUser()
y lo usamos para hacer exactamente lo que podría pensar: solicitar datos de usuario desde el punto final API y recuperarlos para nuestra aplicación. Fetch es una API basada en promesas que devuelve un objeto de respuesta. Entonces, utilizamos el json()
método para obtener el objeto de respuesta que se almacena en los datos y se usa para actualizar el estado de los usuarios en nuestra aplicación. También necesitamos cambiar el estado de isLoading
para false
que nuestra aplicación sepa que la carga se ha completado y todo está claro para representar los datos.
El hecho de que Fetch esté basado en promesas significa que también podemos detectar errores utilizando el .catch()
método. Cualquier error encontrado se utiliza como valor para actualizar el estado de nuestro error. ¡Práctico!
La primera vez que se procesa la solicitud, los datos no se habrán recibido; Puede tardar unos segundos. Queremos activar el método para buscar a los usuarios cuando se pueda acceder al estado de la aplicación para realizar una actualización y volver a renderizar la aplicación. React componentDidMount()
es el mejor lugar para esto, por lo que colocaremos el fetchUsers()
método allí.
componentDidMount() { this.fetchUsers();}
Uso de Fetch con API propia
Hasta ahora, hemos visto cómo utilizar los datos de otra persona en una aplicación. Pero ¿qué pasa si trabajamos con nuestros propios datos en nuestra propia API? Eso es lo que vamos a tratar ahora.
Cree una API que esté disponible en GitHub. La respuesta JSON que se obtiene se coloca en AWS; Eso es lo que usaremos para este tutorial.
Como hicimos antes, creemos nuestro componente y configuramos algún estado predeterminado.
class App extends React.Component { state = { isLoading: true, posts: [], error: null } render() { React.Fragment /React.Fragment }}
Nuestro método para recorrer los datos será diferente del que usamos antes, pero solo debido a la estructura de los datos, que será diferente. Puedes ver la diferencia entre nuestra estructura de datos aquí y la que obtuvimos de JSONPlaceholder .
Así es como render()
verá el método para nuestra API:
render() { const { isLoading, posts, error } = this.state; return ( React.Fragment h1React Fetch - Blog/h1 hr / {!isLoading ? Object.keys(posts).map(key = Post key={key} body={posts[key]} /) : h3Loading.../h3} /React.Fragment );}
Vamos a descomponer la lógica
{ !isLoading ? Object.keys(posts).map(key = Post key={key} body={posts[key]} /) : h3Loading.../h3}
Cuando isLoading
no es así true
, devolvemos una matriz, la mapeamos y pasamos la información al componente Publicar como accesorios. En caso contrario, mostraremos un mensaje “Cargando…” mientras la aplicación esté funcionando. Muy similar a antes.
El método para recuperar publicaciones será similar al utilizado en la primera parte.
fetchPosts() { // The API where we're fetching data from fetch(`https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/posts.json`) // We get a response and receive the data in JSON format... .then(response = response.json()) // ...then we update the state of our application .then( data = this.setState({ posts: data, isLoading: false, }) ) // If we catch errors instead of a response, let's update the app .catch(error = this.setState({ error, isLoading: false }));}
Ahora podemos llamar al fetchPosts
método dentro de un componentDidMount()
método.
componentDidMount() { this.fetchPosts();}
En el componente Publicación, asignamos los accesorios que recibimos y representamos el título y el contenido de cada publicación:
const Post = ({ body }) = { return ( div {body.map(post = { const { _id, title, content } = post; return ( div key={_id} h2{title}/h2 p{content}/p hr / /div ); })} /div );};
¡Ahí lo tenemos! Ahora sabemos cómo utilizar la API Fetch para solicitar datos de diferentes fuentes y utilizarlos en una aplicación. Chocar los cinco. ✋
ejes
Bueno, hemos pasado una buena cantidad de tiempo analizando la API Fetch y ahora vamos a centrar nuestra atención en axios.
Al igual que la API Fetch, axios es una forma de realizar una solicitud de datos para utilizar en nuestra aplicación. Axios se destaca porque permite enviar una solicitud asincrónica a puntos finales REST. Esto resulta útil cuando se trabaja con la API REST en un proyecto React, por ejemplo, un CMS WordPress sin interfaz gráfica.
Existe un debate en curso sobre si Fetch es mejor que axios y viceversa. No vamos a profundizar en eso aquí porque, bueno, puedes elegir la herramienta adecuada para el trabajo correcto. Si tienes curiosidad sobre los puntos de cada lado, puedes leer aquí y aquí.
Uso de axios con una API de terceros
Como hicimos con Fetch API, comenzamos solicitando datos de una API. Para esto, buscaremos usuarios aleatorios de la API de usuario aleatorio.
Primero, creamos el componente de la aplicación como lo hemos hecho antes:
class App extends React.Component { state = { users: [], isLoading: true, errors: null }; render() { return ( React.Fragment /React.Fragment ); }}
La idea sigue siendo la misma: verificar si la carga está en proceso y mostrar los datos que obtenemos o informar al usuario que las cosas aún se están cargando.
Para realizar la solicitud a la API, necesitaremos crear una función. Llamaremos a la función getUsers()
. Dentro de ella, realizaremos la solicitud a la API mediante axios. Veamos cómo se ve esto antes de explicarlo más.
getUsers() { // We're using axios instead of Fetch axios // The API we're requesting data from .get("https://randomuser.me/api/?results=5") // Once we get a response, we'll map the API endpoints to our props .then(response = response.data.results.map(user = ({ name: `${user.name.first} ${user.name.last}`, username: `${user.login.username}`, email: `${user.email}`, image: `${user.picture.thumbnail}` })) ) // Let's make sure to change the loading state to display the data .then(users = { this.setState({ users, isLoading: false }); }) // We can still use the `.catch()` method since axios is promise-based .catch(error = this.setState({ error, isLoading: false }));}
Bastante diferente de los ejemplos de Fetch, ¿verdad? La estructura básica es bastante similar, pero ahora nos dedicamos a mapear datos entre los puntos finales.
La solicitud GET se pasa desde la URL de la API como parámetro. La respuesta que obtenemos de la API contiene un objeto llamado data
y que contiene otros objetos. La información que queremos está disponible en data.results
, que es una matriz de objetos que contienen los datos de usuarios individuales.
Aquí vamos nuevamente llamando a nuestro método dentro del componentDidMount()
método:
componentDidMount() { this.getUsers();}
Alternativamente, puedes hacer esto y básicamente combinar estos dos primeros pasos:
componentDidMount() { axios .get("https://randomuser.me/api/?results=5") .then(response = response.data.results.map(user = ({ name: `${user.name.first} ${user.name.last}`, username: `${user.login.username}`, email: `${user.email}`, image: `${user.picture.thumbnail}` })) ) .then(users = { this.setState({ users, isLoading: false }); }) .catch(error = this.setState({ error, isLoading: false }));}
Si está codificando localmente desde su máquina, puede editar temporalmente la getUsers()
función para que se vea así:
getUsers() { axios .get("https://randomuser.me/api/?results=5") .then(response = console.log(response)) .catch(error = this.setState({ error, isLoading: false }));}
Tu consola debería tener algo similar a esto:
Recorremos la matriz de resultados para obtener la información que necesitamos para cada usuario. Luego, la matriz de usuarios se utiliza para establecer un nuevo valor para nuestro users
estado. Una vez hecho esto, podemos cambiar el valor de isLoading
.
De forma predeterminada, isLoading
está configurado en true
. Cuando se actualiza el estado de users
, queremos cambiar el valor de isLoading
a , false
ya que esta es la señal que nuestra aplicación busca para realizar el cambio de “Cargando…” a datos renderizados.
render() { const { isLoading, users } = this.state; return ( React.Fragment h2Random User/h2 div {!isLoading ? ( users.map(user = { const { username, name, email, image } = user; return ( div key={username} p{name}/p div img src={image} alt={name} / /div p{email}/p hr / /div ); }) ) : ( pLoading.../p )} /div /React.Fragment );}
Si registra el users
estado en la consola, verá que es una matriz de objetos:
La matriz vacía muestra el valor antes de obtener los datos. Los datos devueltos contienen solo los valores , name
y de los usuarios individuales porque esos son los puntos finales que mapeamos. Hay muchos más datos disponibles en la API, por supuesto, pero tendríamos que agregarlos a nuestro método.username
email address
image
getUsers
Usar axios con tu propia API
Ha visto cómo usar axios con una API de terceros, pero podemos ver cómo es solicitar datos de nuestra propia API, tal como lo hicimos con la API Fetch. De hecho, usamos el mismo archivo JSON que usamos para Fetch para que podamos ver la diferencia entre los dos enfoques.
Aquí está todo junto:
class App extends React.Component { // State will apply to the posts object which is set to loading by default state = { posts: [], isLoading: true, errors: null }; // Now we're going to make a request for data using axios getPosts() { axios // This is where the data is hosted .get("https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/posts.json") // Once we get a response and store data, let's change the loading state .then(response = { this.setState({ posts: response.data.posts, isLoading: false }); }) // If we catch any errors connecting, let's update accordingly .catch(error = this.setState({ error, isLoading: false })); } // Let's our app know we're ready to render the data componentDidMount() { this.getPosts(); } // Putting that data to use render() { const { isLoading, posts } = this.state; return ( React.Fragment h2Random Post/h2 div {!isLoading ? ( posts.map(post = { const { _id, title, content } = post; return ( div key={_id} h2{title}/h2 p{content}/p hr / /div ); }) ) : ( pLoading.../p )} /div /React.Fragment ); }}
La principal diferencia entre este método y el uso de axios para recuperar datos de un tercero es cómo se formatean los datos. De esta manera obtenemos JSON directo en lugar de mapear puntos finales.
Los datos de publicaciones que obtenemos de la API se utilizan para actualizar el valor del posts
estado del componente. Con esto, podemos mapear la variedad de publicaciones en render()
. Luego obtendremos el id
y title
de content
cada publicación usando la desestructuración de ES6, que luego se presenta al usuario.
Como hicimos antes, lo que se muestra depende del valor de isLoading
. Cuando establecimos un nuevo estado para posts
usar los datos obtenidos de la API, también tuvimos que establecer un nuevo estado para isLoading
. Luego, finalmente podemos informarle al usuario que se están cargando datos o representar los datos que hemos recibido.
Asíncrono y espera
Otra cosa que nos permite hacer el nate de axios basado en promesas es aprovechar es async
y await
. Usando esto, la getPosts()
función se verá así.
async getPosts() { const response = await axios.get("https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/posts.json"); try { this.setState({ posts: response.data.posts, isLoading: false }); } catch (error) { this.setState({ error, isLoading: false }); }}
Instancia base
Con axios, es posible crear una instancia base donde colocamos la URL de nuestra API de la siguiente manera:
const api = axios.create({ baseURL: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/posts.json"});
…entonces úsalo de esta manera:
async getPosts() { const response = await api.get(); try { this.setState({ posts: response.data.posts, isLoading: false }); } catch (error) { this.setState({ error, isLoading: false }); }}
Simplemente una forma agradable de abstraer la URL de la API.
¡Ahora, registra todos los datos!
A medida que creas aplicaciones React, te encontrarás con muchos escenarios en los que querrás manejar datos desde una API. Esperamos que ahora te sientas preparado y preparado para trabajar con datos de una variedad de fuentes con opciones sobre cómo solicitarlos.
¿Quieres jugar con más datos? Sarah escribió recientemente los pasos para crear su propia API sin servidor a partir de una lista de API públicas.
Deja una respuesta