Header Ads Widget

Ticker

6/recent/ticker-posts

Realizar llamadas a la API AJAX en React: Axios vs jQuery vs Fetch API con ejemplo GET & POST

 A lo largo de este tutorial de AjAX con React , cubriremos diferentes formas de hacer AJAX en React (Axios, jQuery y la API Fetch). Veremos por ejemplo, cómo utilizar el navegador de Fetch API para enviar una petición HTTP (GET y POST) para Reddit y desde donde se pueden hacer llamadas AJAX en un Reaccionar decir, el componente componentDidMount()vs componentWillMount()vs el constructor de la clase ES6.

Aprenderemos, con un simple ejemplo, cómo realizar solicitudes AJAX o llamadas API (GET, POST, PUT y DELETE) para buscar, crear, actualizar y eliminar datos usando React a través de diferentes mecanismos como la biblioteca Axios , XMLHttpRequest o el API de recuperación del navegador moderno .

React es una biblioteca de vistas, para crear interfaces de usuario o UI, no un marco completo como, por ejemplo, Angular o AngularJS. En arquitecturas MVC, React representa la parte V iew. Entonces, si ha utilizado un marco del lado del cliente antes, notará la falta de muchas abstracciones, como servicios para realizar llamadas HTTP (equivalente a $ http en AngularJS).

Entonces, si está preguntando cuál es el equivalente de React para enviar llamadas AJAX? ¡No lo hay!

No debe considerar esto como una debilidad de la biblioteca porque se supone que React no debe manejar todas las tareas que generalmente manejan los marcos. El propósito de React es renderizar componentes sin estado (volcar componentes sin datos) y componentes con estado usando datos de accesorios y estado (que generalmente se obtienen de un servidor API).

¿Cómo obtener datos de servidores HTTP en React?

Entonces, ¿cómo obtener datos de un servidor HTTP remoto? o cómo hacer llamadas a la API?

Tiene una gran cantidad de opciones a su disposición, desde bibliotecas externas hasta API de navegador estándar. Todo lo que tiene que hacer es elegir la solución adecuada para sus necesidades.

Elegir el mecanismo de llamada HTTP correcto

Hay muchas bibliotecas, con diferentes características, que se pueden utilizar para obtener datos de servidores remotos.

  • Puede utilizar Axios si se siente cómodo trabajando con JavaScript Promises.
  • Si te gusta trabajar con estándares de vanguardia, puedes usar la fetchAPI del navegador
  • También puede usar jQuery, pero no se recomienda incluir toda la biblioteca solo por hacer llamadas a la API.
  • Puede utilizar la interfaz XMLHttpRequest .

Llamar a las API mediante la API Fetch

Veamos ahora un ejemplo práctico, usando la API de recuperación del navegador.

Crearemos una aplicación React simple que envía llamadas API al servidor Reddit para buscar algunas publicaciones subreddit .

Crear un nuevo proyecto de React

Así que adelante y crea un nuevo proyecto React. Estoy usando y recomendando create-react-app porque le ahorra la molestia de configurar WebPack y le permite generar rápidamente un proyecto inicial para construir su aplicación.

Instalación de create-react-app

Si decide seguir este camino, puede usar npm para instalar create-react-app con:

npm install -g create-react-app

Generando un nuevo proyecto React

Ahora puedes generar un nuevo proyecto de React con:

create-react-app react-ajax-demo
cd react-ajax-demo
npm start

¿Cómo utilizar la API de Fetch?

Según Mozilla MDN

La API Fetch proporciona una interfaz JavaScript para acceder y manipular partes de la canalización HTTP, como solicitudes y respuestas. También proporciona un método global fetch () que proporciona una forma sencilla y lógica de recuperar recursos de forma asincrónica a través de la red.

Ahora busquemos algunos datos de Reddit . En src/App.jsla actualización del código para reflejar estos cambios:


import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {

  constructor(props) {
    super(props);

    this.state = {
      posts: []
    };
  }  
  fetchFirst(url) {
    var that = this;
    if (url) {
      fetch('https://www.reddit.com/r/' + url + '.json').then(function (response) {
        return response.json();
      }).then(function (result) {

        //console.log(result.data.children);

        that.setState({ posts: result.data.children, lastPostName: result.data.children[result.data.children.length - 1].data.name });

        console.log(that.state.posts);
      });
    }
  }  
  componentWillMount() {

      this.fetchFirst("reactjs");

  }    
  render() {

    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">React AJAX Example</h1>
        </header>
        <p className="App-intro">
          <ul>
            {this.state.posts.map(post =>
              <li key={post.id}>{post.title}</li>
            )}
          </ul>          
        </p>
      </div>
    );
  }
}

export default App;

Justo en el fetchFirst()método, estamos enviando una solicitud GET para obtener datos 'https://www.reddit.com/r/' + url + '.json'usando el siguiente código:

fetch('https://www.reddit.com/r/' + url + '.json').then(function (response) {
        return response.json();
}).then(function (result) {
    console.log(result.data.children);
});

La API es simple, el único argumento requerido es el URI del recurso. En nuestro ejemplo, es un archivo JSON pero puede ser cualquier tipo de recurso, como una imagen u otros tipos.

Sin parámetros adicionales fetch(url)envía una solicitud GET HTTP por defecto.

También puede llamar a otros métodos HTTP como POST, PUT o DELETE especificando explícitamente el nombre del método en el segundo argumento. Por ejemplo, así es como enviamos una solicitud POST confetch()

var form = new FormData(document.getElementById('login-form'));
fetch("/login", {
  method: "POST",
  body: form
});

¿Dónde hacer solicitudes AJAX: componentWillMount vs componentDidMount?

Una aplicación React es un conjunto de componentes con un componente raíz, principal y de nivel superior y componentes secundarios (y secundarios de secundarios) que se pueden visualizar como una estructura de árbol. En la comunidad React surgen muchas preguntas: ¿cómo manejar los datos? ¿Cómo fluyen los datos desde el componente donde se obtienen a otros componentes? y lo más importante, ¿dónde colocar el código para obtener datos?

En el ejemplo anterior, llamamos a la lógica de obtención de datos del componentWillMount()evento de ciclo de vida que se llama cuando el componente está a punto de montarse, antes del primer renderizado del componente.

Hay muchos lugares donde puede obtener datos como:

  • El método render () del componente: ¡es una mala idea! debe evitar colocar cualquier código asincrónico, código que cambie el estado de la aplicación o cause efectos secundarios dentro del render()método del componente .

  • El evento del ciclo de vida componentDidMount(): es el lugar recomendado según los documentos de React.

  • El evento del ciclo de vida componentWillMount(): no se recomienda, según los documentos de React.

  • El constructor del componente en ES6: ¡se considera un anti-patrón! Pero se puede utilizar igual que componentWillMount().

Entonces, veamos las mejores prácticas que debe seguir al obtener datos.

Obteniendo datos dentro del evento componentDidMount ()

Este es el enfoque más simple. Obtenemos datos del servidor remoto en componentDidMount()lugar de componentWillMount()para evitar cualquier efecto secundario de la fetch()API.

componenteDidMount () vs componenteWillMount ()

El componentWillMount()método se llama justo antes del primer renderizado del componente. Eso puede engañar a cualquiera para que piense que es el mejor lugar para obtener datos. ¡Pero ese no es el caso! debido a que las llamadas de recuperación son asincrónicas, lo que significa que es posible que la llamada no regrese antes de la representación del componente, lo que hace que el componente se muestre con datos vacíos. Hay algunas precauciones que puede tomar, como configurar el estado inicial para que el componente se procese correctamente hasta que lleguen los datos y active otro ciclo de procesamiento.

El componentDidMount()método se llama después del primer renderizado del componente, por lo que aquí es donde puede colocar de forma segura cualquier código asincrónico que obtenga datos, tenga efectos secundarios o manipule el DOM.

  • Cuando está adoptando este enfoque, ya ha configurado el estado inicial, correctamente, para manejar datos que aún no están disponibles o el estado no definido.

  • Para la renderización del lado del servidor, componentWillMount()se llamará dos veces desde el servidor y nuevamente desde el cliente, por lo que las solicitudes para recuperar datos se enviarán dos veces haciendo un viaje de ida y vuelta innecesario al servidor. Por otro lado, componentDidMount()se llama solo una vez en el cliente.

Nuestro ejemplo se actualizará a algo como esto:

componentDidMount() {
    this.fetchFirst("reactjs");
} 

componentWillMount () vs constructor

En ES6 React, el constructor se llama justo antes de crear una instancia de la clase, por lo que la pregunta es ¿se puede descartar componentWillMount()a favor del constructor de la clase cuando se usan las clases de JavaScript 2015 (ES6)?

Aparentemente componentWillMount(), el evento del ciclo de vida solo es necesario si está utilizando React con JavaScript antiguo (es decir, ES5), React.createClass()método en el que no puede definir un constructor. Por lo tanto, podemos asumir que se puede usar el constructor en lugar del evento del ciclo de vida posterior al montaje. ¡Pero eso no es 100% correcto! porque React lanza una advertencia si hay un efecto secundario en el constructor de su componente pero no en el componentWillMount()evento. Por lo tanto, es mejor evitar el uso del constructor si su código necesita actualizar el estado en otros componentes. También vimos anteriormente que componentWillMount()está desanimado frente componentDidMount()a los desarrolladores de React. Como última conclusión: use el constructor para cualquier código de inicialización que no produzca efectos secundarios, como actualizaciones de estado, y use lo componentDidMount()contrario. Incluso hay un problema abierto en el repositorio de React paradesaprobar el evento posterior al montaje .

Pasando datos a través de accesorios

Otro enfoque es pasar datos al componente secundario de un padre. Pero, por supuesto, el componente principal también debería evitar el enfoque anterior de obtener datos, así que, ¿dónde? El padre puede usar los ganchos de React Router (como el gancho onEnter ()) para obtener datos y luego pasarlos a los componentes secundarios a través de accesorios .

En nuestro ejemplo simple, solo tenemos un componente, pero esto se puede factorizar fácilmente en algo como:

Fetch.js


export default {
fetchFirst: function(url){
    fetch('https://www.reddit.com/r/' + url + '.json').then(function (response) {
            return response.json();
    }).then(function (result) {
         return result.data.children;   
    }); 
}  
}

RedditPost.js

import React from "react";

class RedditPost extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      title: props.title,
      id: props.id
    }
  }

  componentWillReceiveProps(nextProps) {
    this.setState(nextProps);
  }

  render() {
            <li key={this.state.id}>{this.state.title}</li>
      );
    }
  }
}

RedditPost.propTypes = {
  id: React.PropTypes.number,
  title: React.PropTypes.string
};

RedditPost.defaultProps = {
  id: null,
  title: ""

};

export default RedditPost;

App.js

import fetchFirst from "./Fetch";

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {

  constructor(props) {
    super(props);

    this.state = {
      posts: []
    };
  }  

  componentDidMount() {

      fetchFirst("reactjs").then((posts)=>{
          this.state.posts = posts;
      });

  }    
  render() {

    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">React AJAX Example</h1>
        </header>
        <p className="App-intro">
          <ul>
            {this.state.posts.map(post =>
              <RedditPost {...post}/>
            )}
          </ul>          
        </p>
      </div>
    );
  }
}

export default App;

Usando Redux State Manager

El tercer enfoque es utilizar un administrador de estado como Redux. En este caso, los datos se pueden recuperar desde cualquier lugar de su código y luego almacenarse en una tienda global donde están disponibles para todos los demás componentes.

Conclusión

AJAX permite recuperar datos y luego actualizar la interfaz de usuario sin actualizar la página. Es un requisito para las aplicaciones modernas actuales. Los marcos del lado del cliente incorporan servicios para realizar llamadas HTTP fácilmente, pero para bibliotecas como React, debe confiar en otras bibliotecas o, mejor aún, usar los estándares del navegador: la antigua interfaz XMLHttpRequest, que es bastante compleja (pero puede envolverla dentro de funciones o usar un biblioteca externa como jQuery), o la API de recuperación del navegador moderno (en caso de que desee admitir navegadores antiguos, puede usar polyfills).

Los próximos tutoriales cubrirán:

  • Un ejemplo CRUD completo con React, Fetch API (en el front-end), PHP y MySQL (en el backend)
  • Un sistema de autenticación básico con inicio de sesión y registro usando React, Fetch API, PHP y MySQL.

Publicar un comentario

0 Comentarios