¿Cómo utilizar el Hook useContext? Comunicación de componentes funcionales

Inicioreact jsHook useContext
¿Cómo utilizar el Hook useContext? Comunicación de componentes funcionales

by Juan Carlos García

24-Oct-2023

(4)

Suscribirme al canal:

Hola viajero, hoy vamos a ver el funcionamiento del Hook useContext, con el cual podrás manipular el contexto de tus componentes funcionales y, así, comunicarlos tal y como lo hacemos a través de API Context.

En esta clase lo que vamos hacer es actualizar el ejemplo que hicimos en el capítulo de API Context, así que, te dejo el link a ese post por si no lo has visto y puedas comprender mejor esta clase.

¡No te puedes perder las nuevas clases 🧐!

React JS

React JS

React.js: El mejor curso gratuito de React.js desde cero.

¿Que es React JSX?

¿Que es React JSX?

Guía para principiantes de React JSX: ¿Qué es React JSX? Introducción a React JSX

Componentes y propiedades

Componentes y propiedades

Components and Props React.js, Manejo de propiedades y componentes en React

State y Ciclo de vida en React

State y Ciclo de vida en React

State And Lifecycle: Comprendiendo el State y Ciclo de vida de los componentes en React.js

Refs React

Refs React

¿Qué son las React Refs y para que sirven? Uso de las Refs y manejo del DOM en React.js

Listas y condiciones en React

Listas y condiciones en React

Keys and List: ¿Cómo manejar las listas y condicionales en React JS?

Formularios en React

Formularios en React

Formularios en React: ¿Cómo manejar los formularios en React.js con input controlados y no controlados?

React develepor tools

React develepor tools

React Developer Tools: ¿Cómo analizar el comportamiento y estado de nuestros componentes en React.js?

API Context

API Context

API Context en React: ¿Cómo comunicar componentes mediante API Context en React.js?

Higher Order Component

Higher Order Component

HOC en React.js: ¿Cómo utilizar los High Order Component (HOC) ?

Children en React JS

Children en React JS

Children en React.js: Manejo avanzado de Children en React.js, composición de componentes.

PropTypes en React

PropTypes en React

PropType en React.js: ¿Cómo validar datos a través de PropType en React.js?

Hooks en React JS

Hooks en React JS

Master de Hooks en React JS: ¿Qué es un Hook en React.js? Tipos, funcionamiento y características.

Hook useState

Hook useState

useState: ¿Cómo utilizar el Hook useState en React.js?

Hook useEffect

Hook useEffect

Hook useEffect: ¿Qué es el Hook useEffect? ¿Cómo utilizarlo correctamente y qué reglas seguir?

Hook useContext

Hook useContext

¿Cómo utilizar el Hook useContext? Comunicación de componentes funcionales

Hook useReducer

Hook useReducer

¿Cómo utilizar el Hook useReducer en React.js?

React memo

React memo

Memorizar componentes a través de React.memo en React.js

Hook useCallback

Hook useCallback

Utilizando los Hooks useCallback y useMemo en React.js

🧐 Autoevaluación: Hook useContext

¿Qué es useContext?

¿Cuál es el uso correcto de useContext?

¿Al useContext le debes pasar el Consumer y Provider por separado?

Compra tu libro de React.js

Continua aprendiendo con estos libros que puedes comprar desde tu casa.

¿Qué aprenderás de useContext?

  • Declaración de useContext.
  • Migrar de API Context en su forma tradicional a Hooks en componentes funcionales.
  • Comprobarás que al utilizar este Hook, tu código será más compacto y fácil de leer.

Repositorio

  • Puedes descargar el código dando clic aquí.
  • O puedes clonar el repositorio y cambiarte a la rama "usecontext".
git clone https://github.com/EWebik/react-js.git
git checkout usecontext

¿Qué es y para qué sirve el Hook useContext?

Al useContext lo podemos definir como un Hook que permite comunicar componentes funcionales a través del contexto en React.

Entonces, este Hook recibe un objeto de contexto y retorna el valor del contexto actual, el cual si recordamos un poco, el valor del contexto actual lo asignamos a través de value en el provider:

<MyContext.Provider value={value}>

Declaración de useContext

Como otros Hooks que ya hemos visto, lo podemos declarar dentro de hilo principal de nuestro componente.

const context = useContext();

Uso correcto de useContext

Ahora, recuerda que useContext debe recibir el contexto como argumento y, además, podemos obtener a través de desestructuración, el valor del contexto.

const context = useContext(Context);

O

const {mensaje, index, actualizarMensaje} = useContext(Context);

Uso incorrecto de useContext

Cuando utilicemos este Hook debes pasarle como argumento la variable de contexto como tal y nunca pasar el provider o el consumer. Aquí algunos ejemplos incorrectos de su uso.

useContext(MyContext.Consumer)
useContext(MyContext.Provider)

📌 Nota: Recuerda que al agregar useContext a tu componente funcional, este siempre se volverá a renderizar cuando el contexto cambié.

Ejemplo de useContext

Bien, hagamos un ejemplo con este Hook, lo que vamos hacer es migrar API Context a useContext, y lo vamos hacer utilizando el código que desarrollamos en el capítulo 9 de este curso de React JS. Este es el código que hicimos.

En dicho ejemplo lo que hicimos fue comunicar nuestros componentes a través de API Context, solo que ahora implementaremos useContext en el componente Hijo1, para que veas en acción a este Hook.

Comencemos revisando el código original y el que vamos a modificar.

import React,{useState,useRef} from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

//Introducción API Context React

//DECLARACIÓN
const {Provider, Consumer} = React.createContext();


const Hijo1 = (props)=>{
  return(
    <Consumer>
      {
        ({mensaje, index, actualizarMensaje}) =>(
          <div className="hijo">
            <h2>Hijo 1</h2>
            {
              mensaje !== "" ?(
                <p className={
                  index === 0 ? 'colorPadre':
                  index === 1 ? 'colorHijo1':
                  index === 2 ? 'colorHijo2':''
                }>{
                  ((index === 0 ? 'Padre dice:':
                    index === 1 ? 'Hijo 1 dice:':
                    index === 2 ? 'Hijo 2 dice:':'')
                    + ' ' + mensaje)
                }</p>
              ):("")
            }
            <textarea
              rows="5"
              onChange={(e)=>{
                actualizarMensaje(e,1);
              }} />
          </div>
        )
      }
    </Consumer>
  )
}

const Hijo2 = (props)=>{
  return(
    <Consumer>
    {
      ({mensaje, index, actualizarMensaje}) =>(
        <div className="hijo">
          <h2>Hijo 2</h2>
          {
            mensaje !== "" ?(
              <p className={
                index === 0 ? 'colorPadre':
                index === 1 ? 'colorHijo1':
                index === 2 ? 'colorHijo2':''
              }>{
                ((index === 0 ? 'Padre dice:':
                  index === 1 ? 'Hijo 1 dice:':
                  index === 2 ? 'Hijo 2 dice:':'')
                  + ' ' + mensaje)
              }</p>
            ):("")
          }
          <textarea
            rows="5"
            onChange={(e)=>{
              actualizarMensaje(e,2);
            }} />
        </div>
      )
    }
    </Consumer>
  )
}

class Padre extends React.Component{
  constructor(props){
    super(props)
    this.state={
      mensaje:"",
      index:0
    }
  }

  actualizarMensaje = (e, index)=>{
    const {value} = e.target;
    this.setState({
      ...this.state,
      mensaje:value,
      index
    })
  }

  render(){
    return(
      <Provider value={{
        mensaje: this.state.mensaje,
        index: this.state.index,
        actualizarMensaje:this.actualizarMensaje
      }}>
        <div className="padre">
          <h1>EWebik - API Context</h1>
          {
            this.state.mensaje !== "" ?(
              <p className={
                this.state.index === 0 ? 'colorPadre':
                this.state.index === 1 ? 'colorHijo1':
                this.state.index === 2 ? 'colorHijo2':''
              }>{
                ((this.state.index === 0 ? 'Padre dice:':
                  this.state.index === 1 ? 'Hijo 1 dice:':
                  this.state.index === 2 ? 'Hijo 2 dice:':'')
                  + ' ' + this.state.mensaje)
              }</p>
            ):("")
          }
          <textarea
            rows="5"
            onChange={(e)=>{
              this.actualizarMensaje(e,0);
            }} />
          <div className="hijos">
            <Hijo1 />
            <Hijo2 />
          </div>
        </div>
      </Provider>
    )
  }
}

ReactDOM.render(
  <Padre />,
  document.getElementById('root')
);
  1. Lo primero que vamos hacer es redefinir la declaración de context:
//Cambiar de
const {Provider, Consumer} = React.createContext();

//Por
const Context = React.createContext();
  1. Utilizando notación de punto, agregamos el nuevo marcado a nuestro componentes: Padre e Hijo2.
class Padre extends React.Component{
  
  ...

  render(){
    return(
      <Context.Provider value={{
        mensaje: this.state.mensaje,
        index: this.state.index,
        actualizarMensaje:this.actualizarMensaje
      }}>
        ...
      </Context.Provider>
    )
  }
}

 

const Hijo2 = (props)=>{
  return(
    <Context.Consumer>
    {
      ({mensaje, index, actualizarMensaje}) =>(
        ...
      )
    }
    </Context.Consumer>
  )
}
  1. Mientras tanto en el componente Hijo3, vamos a agregar useConext con lo cual migramos API Context en su forma tradicional a Hooks.
const Hijo1 = (props)=>{
  const {mensaje, index, actualizarMensaje} = useContext(Context);
  return(
    <div className="hijo">
      <h2>Hijo 1</h2>
      {
        mensaje !== "" ?(
          <p className={
            index === 0 ? 'colorPadre':
            index === 1 ? 'colorHijo1':
            index === 2 ? 'colorHijo2':''
          }>{
            ((index === 0 ? 'Padre dice:':
              index === 1 ? 'Hijo 1 dice:':
              index === 2 ? 'Hijo 2 dice:':'')
              + ' ' + mensaje)
          }</p>
        ):("")
      }
      <textarea
        rows="5"
        onChange={(e)=>{
          actualizarMensaje(e,1);
        }} />
    </div>
  )
}
  • En primer lugar vemos que dentro del hilo principal agregamos el Hook.
const {mensaje, index, actualizarMensaje} = useContext(Context);
  • Eliminamos el marcado de API Context
<Context.Consumer>
    {
      ({mensaje, index, actualizarMensaje}) =>(
      
      ...
  
       }   
</Context.Consumer>
  

Con estos imples cambios hacemos nuestro componente más compacto y fácil de leer.

Aquí el código completo del uso del hook useContext

import React,{useState,useRef, useContext} from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

//Hook useContext

//DECLARACIÓN
const Context = React.createContext();


const Hijo1 = (props)=>{
  const {mensaje, index, actualizarMensaje} = useContext(Context);
  return(
    <div className="hijo">
      <h2>Hijo 1</h2>
      {
        mensaje !== "" ?(
          <p className={
            index === 0 ? 'colorPadre':
            index === 1 ? 'colorHijo1':
            index === 2 ? 'colorHijo2':''
          }>{
            ((index === 0 ? 'Padre dice:':
              index === 1 ? 'Hijo 1 dice:':
              index === 2 ? 'Hijo 2 dice:':'')
              + ' ' + mensaje)
          }</p>
        ):("")
      }
      <textarea
        rows="5"
        onChange={(e)=>{
          actualizarMensaje(e,1);
        }} />
    </div>
  )
}

const Hijo2 = (props)=>{
  return(
    <Context.Consumer>
    {
      ({mensaje, index, actualizarMensaje}) =>(
        <div className="hijo">
          <h2>Hijo 2</h2>
          {
            mensaje !== "" ?(
              <p className={
                index === 0 ? 'colorPadre':
                index === 1 ? 'colorHijo1':
                index === 2 ? 'colorHijo2':''
              }>{
                ((index === 0 ? 'Padre dice:':
                  index === 1 ? 'Hijo 1 dice:':
                  index === 2 ? 'Hijo 2 dice:':'')
                  + ' ' + mensaje)
              }</p>
            ):("")
          }
          <textarea
            rows="5"
            onChange={(e)=>{
              actualizarMensaje(e,2);
            }} />
        </div>
      )
    }
    </Context.Consumer>
  )
}

class Padre extends React.Component{
  constructor(props){
    super(props)
    this.state={
      mensaje:"",
      index:0
    }
  }

  actualizarMensaje = (e, index)=>{
    const {value} = e.target;
    this.setState({
      ...this.state,
      mensaje:value,
      index
    })
  }

  render(){
    return(
      <Context.Provider value={{
        mensaje: this.state.mensaje,
        index: this.state.index,
        actualizarMensaje:this.actualizarMensaje
      }}>
        <div className="padre">
          <h1>EWebik - API Context</h1>
          {
            this.state.mensaje !== "" ?(
              <p className={
                this.state.index === 0 ? 'colorPadre':
                this.state.index === 1 ? 'colorHijo1':
                this.state.index === 2 ? 'colorHijo2':''
              }>{
                ((this.state.index === 0 ? 'Padre dice:':
                  this.state.index === 1 ? 'Hijo 1 dice:':
                  this.state.index === 2 ? 'Hijo 2 dice:':'')
                  + ' ' + this.state.mensaje)
              }</p>
            ):("")
          }
          <textarea
            rows="5"
            onChange={(e)=>{
              this.actualizarMensaje(e,0);
            }} />
          <div className="hijos">
            <Hijo1 />
            <Hijo2 />
          </div>
        </div>
      </Context.Provider>
    )
  }
}

ReactDOM.render(
  <Padre />,
  document.getElementById('root')
);

Con simplemente hacer estos cambios, nuestro aplicación funciona exactamente igual, pero ahora es más fácil de entender y leer.

Excelente, no olvides ver el vídeo donde hago todo esto paso a paso, estoy seguro que te va a gustar, no olvides en compartir este post para que llegue a mas colegas que lo necesiten, nos vemos en el siguiente post.

🧐 Autoevaluación: Hook useContext

¿Qué es useContext?

¿Cuál es el uso correcto de useContext?

¿Al useContext le debes pasar el Consumer y Provider por separado?

Juan Carlos

Juan Carlos García

Desarrollador de software / SEO

Durante años he desarrollado plataformas dedicadas al rastreo satelital y varios sitios web que se encuentran en la primera página de Google, y hoy quiero compartir contigo lo que se en tecnologías como: Node JS, PHP, C# y Bases de datos.

Si quieres apoyarme sígueme en mis redes sociales y suscríbete a mi canal de YouTube.

EWebik

Diseño de páginas web y aplicaciones moviles.

© 2024 EWebik