reactjsjavascriptfrontend

Conoce como reutilizar código con los custom hooks de React

Con los nuevos Hooks de React reutilizar código entre tus componentes es muy fácil, conocelos en este artículo.

En el anterior artículo sobre los Hooks de React di una breve introducción a lo que significa esta nueva forma de escribir componentes en React sin la necesidad de escribir una clase, después en el artículo sobre Higher-Order Components enseñe uno de los patrones más utilizados en React para la reutilización de código y en este articulo vamos a ver como usar los Custom Hooks una forma de reutilizar lógica en nuestro componentes usando esta nueva característica.

En el anterior articulo sobre los Hooks di un ejemplo de como renderizar unos datos traídos anteriormente desde una API, ese ejemplo es el siguiente:

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

Ahora, ¿que pasaría si quiero hacer otra petición y así traer datos adicionales?, en este caso tendría que escribir el siguiente código:

 import React, { useEffect, useState, Fragment } from 'react';
 const DataList = () => {
  const [posts, setPosts] = useState( [] )
  const [users, setUsers] = useState( [] )

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

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

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

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

  return (  
    <Fragment>
      <h2>Posts</h2>
      <ul>
        {posts.map(post => <li key={post.id}>{post.title}</li>)}
      </ul>
      <h2>Usuarios</h2>
      <ul>
        {users.map(user => <li key={user.id}>{user.name}</li>)}
      </ul>
    </Fragment>
  )
}

En este código estamos creando otra variable de estado llamada users y en un nuevo useEffect() estamos haciendo la petición que nos consigue estos usuarios de nuestra API, y por último simplemente estamos renderizando cada uno de los usuarios y de los artículos.

El problema con este código es que estamos haciendo dos funciones prácticamente idénticas para traer los usuarios y los artículos, en este tipo de casos es que nos sirven los custom hooks, el cual podemos hacerlo de la siguiente manera:

import { useState, useEffect } from 'react'

function useFetch(url, defaultValue) {
  const [data, setData] = useState(defaultValue)
  const [error, setError] = useState(null)

  useEffect(() => {
    fetch(url)
      .then(response => response.json())
      .then(data => {
        setData(data)
      })
      .catch(err => {
        setError(err)
      })
  }, [])

  return { data, error }
}

export default useFetch

En esta función llamada useFetch() estamos recibiendo por parámetro la url donde queremos hacer la petición y el valor por defecto que queremos que tome nuestra variable data, esto es totalmente valido ya que así sea que estemos usando características de React como el estado y el ciclo de vida en nuestra función, useFetch() sigue siendo una función de Javascript.

Después estamos creando dos variables de estado data y error donde guardaremos los datos de la petición y otra donde guardaremos cualquier error que ocurra durante esta petición, después usando useEffect() que nos permite usar el ciclo de vida de React, hacemos la petición y al final retornamos tanto la data obtenida como el posible error que tengamos.

Para usar nuestro custom hook en nuestro componente solo debemos importar useFetch() y ejecutarlo pasando sus respectivos parámetros de la siguiente manera:

import React, { useEffect, useState } from 'react'
import useFetch from './useFetch'

const DataList = () => {
  const users = useFetch('https://jsonplaceholder.typicode.com/users', [])
  const posts = useFetch('https://jsonplaceholder.typicode.com/posts', [])

  return (
    <Fragment>
      <h2>Usuarios</h2>
      <ul>
        {users.data.map(user => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
      <h2>Posts</h2>
      <ul>
        {posts.data.map(posts => (
          <li key={posts.id}>{posts.title}</li>
        ))}
      </ul>
    </Fragment>
  )
}

export default DataList

Primero que todo estamos asignando a nuestras constantes users y posts el valor de retorno de nuestro custom hook useFetch() que en este caso será un objeto con el resultado de la petición a la url que le estamos indicando y cualquier error que ocurra en ese proceso, con esos datos ya conseguidos los renderizamos en nuestro JSX los posts y los usuarios, accediendo a la propiedad data que fue la que definimos en nuestro hook.

Como puedes ver los hooks vuelven muy fácil poder reutilizar lógica entre diferentes componentes sin necesidad de recurrir a los Higher-Order Components (HOC).

Gracias por leer el articulo, te recomiendo mirar la documentación de los custom hooks y en caso que quieras ver todo el código aqui te dejo el link

reactjsjavascriptfrontend

Sigue leyendo