Solicitud POST HTTP en React

En este tutorial, aprenderá cómo realizar solicitudes POST HTTP en React utilizando los dos métodos principales: Fetch API y Axios. También aprenderá cómo hacer esto en componentes funcionales y de clase en React.

Introducción

Cuando trabajamos con API, a menudo queremos enviar datos al servidor para su procesamiento. Por ejemplo, si tenemos una lista de tareas pendientes y queremos agregarle, tal vez mediante el envío de un formulario, usamos solicitudes POST HTTP para enviar una solicitud con una carga útil para el procesamiento y la persistencia potencial.

En este artículo, aprenderemos cómo realizar solicitudes POST HTTP en React utilizando dos enfoques comunes: Fetch API y Axios. También conoceremos cómo hacer esto en componentes funcionales y basados ​​en clases.

Usando la API Fetch, enviar una solicitud POST HTTP con React es tan fácil como:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// Using Fetch API
fetch('/myserver.endpoint', {
  method: 'POST',
  body: JSON.stringify({
    // Add parameters here
  })
  headers: {
    'Content-type': 'application/json; charset=UTF-8',
  },
})
   .then((response) => response.json())
   .then((data) => {
      console.log(data);
      // Handle data
   })
   .catch((err) => {
      console.log(err.message);
   });

Axios nos brinda una elegante alternativa para enviar solicitudes HTTP POST:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// Using Axios - ensure you first install the package
axios.post('/myserver.endpoint', {
    // Add parameters here
  })
  .then((response) => {
    console.log(response.data);
      // Handle data
  })
  .catch((error) => {
    console.log(error);
  })

Si desea obtener más información sobre estos enfoques y cómo funcionan, ¡lea el resto de la guía!

¿Qué es una solicitud POST HTTP?

Como su nombre lo indica, las solicitudes POST se utilizan para publicar datos en un punto final, que generalmente los procesa y los guarda en una base de datos. Estos datos pueden provenir de un formulario, guardarse en un objeto u obtenerse de otra manera, pero generalmente se convierten en una representación JSON para que la API REST los consuma.

El envío de solicitudes HTTP con cualquier verbo se simplifica gracias a la Fetch API (integrada) y bibliotecas como Axios. Fetch API es un método de navegador incorporado para realizar solicitudes HTTP, mientras que Axios es un paquete externo que debemos instalar en nuestro proyecto antes de usarlo.

Elegir entre estos depende de usted. La API Fetch es más detallada y no funciona con solicitudes asincrónicas, pero Axios es una dependencia externa. Aun así, muchos prefieren trabajar con Axios en lugar de Fetch API. Cubriremos ambos.

Ambos métodos tienen ventajas y desventajas, pero es importante tener en cuenta que pueden manejar los verbos HTTP estándar: POST, GET, PUT, PATCH, DELETE.

{.icon aria-hidden=“true”}

Nota: Como se mencionó anteriormente, aprenderemos cómo realizar solicitudes POST con componentes funcionales usando la API Fetch y los métodos Axios, y luego en componentes basados ​​​​en clases usando la API REST de publicaciones falsas gratuitas de marcador de posición JSON.

En nuestro ejemplo, trabajaremos con una lista de publicaciones que ya hemos obtenido de una API simulada. Crearemos un formulario que tome el título y el cuerpo de una nueva publicación y, una vez enviado, envíe una solicitud POST al servidor simulado para su procesamiento:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import { useState, useEffect } from 'react';

const App = () => {
   const [posts, setPosts] = useState([]);

   useEffect(() => {
      fetch('https://jsonplaceholder.typicode.com/posts?_limit=5')
         .then((res) => res.json())
         .then((data) => {
            console.log(data);
            setPosts(data);
         })
         .catch((err) => {
            console.log(err.message);
         });
   }, []);

   return (
      <>
         <div className="add-post-container">
            <form>
               <input type="text" className="form-control" />
               <textarea className="form-control" cols="10" rows="8"></textarea>
               <button type="submit">Add Post</button>
            </form>
         </div>
         <div className="posts-container">
            {posts.map((post) => {
               return (
                  <div className="post-card" key={post.id}>
                     <h2 className="post-title">{post.title}</h2>
                     <p className="post-body">{post.body}</p>
                     <div className="button">
                        <div className="delete-btn">Delete</div>
                     </div>
                  </div>
               );
            })}
         </div>
      </>
   );
};

export default App;

Ahora hagamos que el formulario sea funcional para que podamos agregar datos a las listas de publicaciones en nuestro sitio web una vez que se envíe el formulario.

Cómo realizar una solicitud POST HTTP en el componente funcional de React

Ahora podemos realizar solicitudes HTTP en componentes funcionales gracias a la introducción de ganchos en React. Anteriormente, los componentes funcionales solo se usaban para representar la interfaz de usuario.

Se crea un componente funcional cuando una función de JavaScript (ya sea estándar o ES6) devuelve un elemento React (JSX).

En lugar de usar el objeto de estado en el método constructor como con los componentes basados ​​en clases, ahora usamos ganchos de React como useState() para almacenar nuestros datos antes de pasarlos a los datos originales.

Cómo realizar una solicitud POST HTTP en el componente funcional de React con la API Fetch

Debido a que Fetch API es un método de navegador incorporado que devuelve una Promesa, usamos los métodos .then() y .catch() para manejar el éxito y el fracaso. También acepta un argumento obligatorio, que es la URL del recurso/API en el que queremos enviar datos POST, así como un argumento que indica la solicitud HTTP, que en nuestro caso es POST:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import { useState, useEffect } from 'react';

const App = () => {
   const [posts, setPosts] = useState([]);
   const [title, setTitle] = useState('');
   const [body, setBody] = useState('');
   
   // ... Fetch posts here
   
   // Handle psosts request
   const handleSubmit = (e) => {
      e.preventDefault();
      fetch('https://jsonplaceholder.typicode.com/posts', {
         method: 'POST',
         body: JSON.stringify({
            title: title,
            body: body,
            userId: Math.random().toString(36).slice(2),
         }),
         headers: {
            'Content-type': 'application/json; charset=UTF-8',
         },
      })
         .then((res) => res.json())
         .then((post) => {
            setPosts((posts) => [post, ...posts]);
            setTitle('');
            setBody('');
         })
         .catch((err) => {
            console.log(err.message);
         });
   };

   return (
      // ... JSX here
   );
};

export default App;

En el código anterior, creamos un método que vincularemos al formulario para que se active cuando se haga clic en el botón Enviar del formulario. Comenzamos usando e.preventDefault() para evitar que la página se vuelva a cargar al enviar el formulario, que generalmente es lo que desea que suceda, pero no funciona tan bien para nuestra demostración:

1
2
3
const handleSubmit = (e) => {
   e.preventDefault();
};

Mirando la llamada fetch(), agregamos la URL como el primer parámetro obligatorio, y el segundo parámetro toma el método de solicitud (POST), el cuerpo y el encabezado:

  • cuerpo: contiene los datos que queremos enviar al extremo de la API, que debemos encadenar, convirtiéndolos en una representación JSON basada en texto.
  • header: especifica el tipo de contenido, que en nuestro caso es application/json, ya que nuestra carga útil se representa como una cadena JSON:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
const handleSubmit = (e) => {
   e.preventDefault();
   fetch('https://jsonplaceholder.typicode.com/posts', {
      method: 'POST',
      body: JSON.stringify({
         title: title,
         body: body,
         userId: Math.random().toString(36).slice(2),
      }),
      headers: {
         'Content-type': 'application/json; charset=UTF-8',
      },
   })
};

Finalmente, debido a que este método devuelve una ‘Promesa’, extraeremos el contenido JSON (respuesta del servidor), actualizaremos el estado de las ‘publicaciones’ para incluir los nuevos datos.

Para manejar los errores, también usamos el método .catch():

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
const handleSubmit = (e) => {
   e.preventDefault();
   fetch({...})
      .then((res) => res.json())
      .then((post) => {
         setPosts((posts) => [post, ...posts]);
         setTitle('');
         setBody('');
      })
      .catch((err) => {
         console.log(err.message);
      });
};

{.icon aria-hidden=“true”}

Advertencia: Por lo general, no almacenará ni procesará datos en el front-end como lo hacemos nosotros, pero dado que la API simulada con la que estamos trabajando en realidad no guardará ni devolverá el nueva publicación: la estamos agregando artificialmente a la lista que devuelve desde la primera solicitud GET. Una vez que la publicación se almacena en la base de datos, podemos realizar otra solicitud al back-end para proporcionar la respuesta para mostrar al usuario. Esta es también la razón por la que el comportamiento predeterminado del envío del formulario es volver a cargar la página, lo que activaría la solicitud GET fetch() inicial y mostraría la nueva publicación junto con las anteriores, automáticamente.

Cómo realizar una solicitud POST HTTP en el componente funcional de React con Axios

Explicamos cómo realizar solicitudes POST con Fetch API en la sección anterior. Ahora, modifiquemos el método handleSubmit() y realicemos solicitudes POST con Axios en su lugar.

Axios es una biblioteca de cliente HTTP que utiliza promesas para facilitar el envío de solicitudes HTTP asincrónicas a puntos finales REST. Debido a que es una biblioteca externa, primero debemos instalarla en nuestro proyecto ejecutando el siguiente comando en el directorio de nuestro proyecto:

1
$ npm install axios

Una vez que hayamos instalado correctamente Axios, podemos proceder a realizar nuestra solicitud POST:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
const handleSubmit = (e) => {
   e.preventDefault();
   axios
      .post('https://jsonplaceholder.typicode.com/posts', {
         title: title,
         body: body,
      })
      .then((res) => {
         setPosts((posts) => [res.data, ...posts]);
         setTitle('');
         setBody('');
      })
      .catch((err) => {
         console.log(err.message);
      });
};

Mirando el código anterior, es mucho más fácil y requiere menos sintaxis que la API Fetch, ya que ya no necesitamos convertir a JSON, trabajar con encabezados e incluso encadenar nuestros datos. Este texto modelo es abstraído por Axios.

Cómo realizar una solicitud POST HTTP en el componente de clase de React

Las solicitudes POST en los componentes de clase se manejan de manera diferente que en los componentes funcionales porque ya no usamos ganchos React y en su lugar usamos el objeto state.

Un componente de clase es una clase ES6 que devuelve JSX y requiere extensiones de React.

Cómo realizar una solicitud POST HTTP en el componente de clase de React con la API Fetch

La solicitud es muy similar a la de los componentes funcionales. Las únicas áreas en las que encontraríamos algunas diferencias son cuando almacenamos datos en estado y cuando usamos valores de estado porque ya no usamos el gancho useState():

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import React, { Component } from 'react';

class App extends Component {

   constructor(props) {
      super(props);
      this.state = {
         posts: [],
      };
   }
   
   // ...   

   handleSubmit = (e) => {
      e.preventDefault();
      fetch('https://jsonplaceholder.typicode.com/posts', {
         method: 'POST',
         body: JSON.stringify({
            title: this.state.title,
            body: this.state.body,
            userId: Math.random().toString(36).slice(2),
         }),
         headers: {
            'Content-type': 'application/json; charset=UTF-8',
         },
      })
         .then((response) => response.json())
         .then((data) => {
            this.setState({ posts: [data, ...this.state.posts] });
            this.setState({ title: '' });
            this.setState({ body: '' });
         })
         .catch((err) => {
            console.log(err.message);
         });
   };

   render() {
      const { posts, title, body } = this.state;
      return (
         // ... JSX here
      );
   }
}

export default App;

Esta vez, ya no declaramos métodos con la palabra clave const. En su lugar, prefijelos con this. Este método se activará cuando se haga clic en el botón de envío del formulario. Dado que es un formulario, comenzamos usando e.preventDefault() para evitar que la página se vuelva a cargar cuando se envía el formulario:

1
2
3
handleSubmit = (e) => {
   e.preventDefault();
};

Tal como aprendimos anteriormente, Fetch API toma dos parámetros. Uno es la URL, mientras que el segundo contiene opciones como el método de solicitud (POST), cuerpo, que es la información que estamos publicando (debe estar en forma de cadena), y luego los encabezados:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
handleSubmit = (e) => {
   e.preventDefault();
   fetch('https://jsonplaceholder.typicode.com/posts', {
      method: 'POST',
      body: JSON.stringify({
         title: this.state.title,
         body: this.state.body,
         userId: Math.random().toString(36).slice(2),
      }),
      headers: {
         'Content-type': 'application/json; charset=UTF-8',
      },
   })
};

Sabiendo que esto es una promesa, ahora podemos adjuntar el método .then() para manejar el éxito y el método .catch() para manejar una situación si hay un error o una falla en la solicitud HTTP.

Cómo realizar una solicitud POST HTTP en el componente de clase de React con Axios

Hemos visto cómo realizar solicitudes HTTP POST en componentes basados ​​en clases. Esto es muy similar a Axios, ya que todo lo que tenemos que hacer es instalar Axios y luego reemplazar el método handleSubmit(), por lo que ahora usamos Axios en lugar de Fetch API:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
handleSubmit = (e) => {
   e.preventDefault();
   axios
      .post('https://jsonplaceholder.typicode.com/posts', {
         title: this.state.title,
         body: this.state.body,
         userId: 1,
      })
      .then((response) => {
         this.setState({ posts: [response.data, ...this.state.posts] });
         this.setState({ title: '' });
         this.setState({ body: '' });
      })
      .catch((error) => console.log(error));
};

Conclusión

En esta guía, aprendimos cómo usar los dos métodos principales en React para realizar solicitudes POST HTTP. También vimos cómo se podían hacer tanto en componentes funcionales como basados ​​en clases, por lo que este artículo nos puede servir independientemente de lo que se use en nuestro proyecto.