REACTJSFRONTENDJAVASCRIPT

Introducción a los hooks de react

10 dic. 2018|Lectura de 5 minutos

Los React hooks permiten la construcción de componentes mucho más limpios y reutilizables, sin la necesidad de escribir componentes dentro de clases.

Hace aproximadamente un mes hubo un gran revuelo en la comunidad de React, dado que en el marco de la React Conf 2018 el equipo detras de React presento una nueva característica llamada Hooks, la cual en el momento de estar escribiendo este post esta en una versión experimental pero se espera que para la version 16.7 de React ya se integre oficialmente a la API de React.

Los hooks son una nueva forma de usar características propias de React como el estado o el ciclo de vida sin la necesidad de escribir una clase que es como se hacia hasta ahora, lo cual no significa que el equipo detras de React piense dejar de usar clases en un futuro cercano ya que hay una gran multitud de proyectos que usan componentes creados de esta manera.

Para ilustrar como funcionan los hooks, voy a crear una serie de ejemplos donde primero lo hare usando clases y despues usando los nuevos hooks de React.

Primero veamos este ejemplo

import React, { Component } from 'react'

class Door extends Component {
  constructor(...props) {
    super(...props)
    this.state = {open: false}
  }

  render() {
    const { open }  = this.state
    return (
      <div>
        <h1>La puerta esta {open ? 'abierta' : 'cerrada'}</h1>  
        <button onClick={() => this.setState({ open: !this.state.open })}>
          {open ? 'Cerrar' : 'Abrir'}
        </button>
      </div>
    )
  }
}

export default Door

En este sencillo ejemplo solo declaramos un estado en el constructor de nuestro componente, renderizamos un mensaje diciendo que una puerta esta abierta o cerrada dependiendo del valor de la propiedad open de nuestro estado y a su vez estamos usando un botón para modificar el valor de nuestro estado.

Ahora realicemos este mismo ejemplo usando los hooks de React

import React, { useState } from 'react'

const Door = () => {
  const [open, setOpen] = useState(false)

  return (
    <div>
      <h1>La puerta esta {open ? 'abierta' : 'cerrada'}</h1>
      <button onClick={() => setOpen(!open)}>
        {open ? 'Cerrar' : 'Abrir'}
      </button>
    </div>
  )
}

export default Door

En este código primero que todo estamos usando el hook useState() el cual nos permite usar la característica de estado en este componente a pesar de no ser una clase, este hook nos recibe como parámetro el valor por defecto que queremos que tenga nuesto estado y nos devuelve un array con dos posiciones, la primera posición es el valor que le asignaremos por defecto en este caso false, y como segunda posición nos devuelve la función que usaremos para actualizar este valor en nuestro componente, despues retornamos nuestro jsx y aqui como se hizo anteriormente usamos un botón para actualizar el valor de open y dependiendo del valor que vaya tomando se renderiza que la puerta esta abierta o cerrada.

Otra de las características que se suelen usar mucho en el desarrollo con React es el ciclo de vida de un componente, para lo cual tambien se pueden usar los hooks.

primero que todo hagamos un ejemplo usando clases

import React, { Component } from 'react';

class DataList extends Component {
  constructor(...props) {
    super(...props)

    this.state = { posts: [] }
  }

  componentDidMount() {
    this.getPosts()
  }

  getPosts() {
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then(response => response.json())
      .then(posts => this.setState({ posts }))
      .catch(err => console.log(err.message))
  }

  render() {
    const { posts } = this.state
    return (
      <ul>
        {posts.map(post => <li key={post.id}>{post.title}</li>)}
      </ul>
    );
  }
}

export default DataList;

En este sencillo ejemplo solo estamos declarando un estado posts como un array, despues en el componentDidMount() que es un método del ciclo de vida que se ejecuta cuando el componente se renderizo, estamos haciendo una peticion a la api de jsonplaceholder, para traernos una lista de posts usando el método getPosts() que nosotros mismos declaramos, actualizamos el estado de los posts y los renderizamos como una lista en el método render().

Ahora hagamos el mismo ejemplo con los React hooks

import React, { useEffect, useState } from 'react';

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

  function getPosts() {
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then(response => response.json())
      .then(posts => setPosts(posts))
      .catch(err => console.log(err.message))
  }

  useEffect(() => {
    getPosts()
  }, [])

  return (  
    <ul>
      {posts.map(post => <li key={post.id}>{post.title}</li>)}
    </ul>
  )
}

export default DataList

En este ejemplo primero que todo estamos definiendo un nuevo estado con useState(), el cual sera por defecto un array vacio, despues estamos definiendo la función getPosts() que sera la encargada de hacer la petición a la API y usando el hook useEffect() es que ejecutamos la función que nos traera los posts, este hook useEffect() nos permitira reemplazar los métodos del ciclo de vida componentDidMount(), componentDidUpdate() y componentWillUnmount(), en este ejemplo estamos usando el useEffect() como si se tratara del componentDidMount(), esto debido al array vacio que le estamos pasando como segundo parámetro, con esto le estamos indicando que solo se va a ejecutar en una ocasión, despues simplemente renderizamos estos nuevos articulos cuando retornemos.

Como pueden ver usar los React hooks nos permiten tener componentes muchos más limpios, sin la necesidad de utilizar una clase, en próximos articulos te mostrare los otros usos de useEffect() y como crear custom hooks lo cual nos permitira reutilizar lógica entre componentes de una forma muy óptima, hasta la próxima.