REACT CONTEXT
Tags: react, frontend, webdev, javascript
Published: 2023-08-15 01:12:51

- [REACT CONTEXT:]
- [¿CUÁNDO USAR CONTEXT?]
- [¿CUÁNDO NO USAR CONTEXT?]
- [¿CÓMO USAR CONTEXT?]
# REACT CONTEXT:

Context es una API de React que permite comunicar información entre los componentes sin recorrer cada nivel del árbol de nuestros componentes.

## DATA FLOW:

React está diseñado para que la información fluya en una sola dirección, desde los componentes superiores hacia abajo. Al seguir ésta regla, el flujo de información es explícito y más fácil de comprender.

## PROP DRILLING:

Aunque React está diseñado para enviar información desde los componentes superiores hacia abajo, **************existen escenarios************** para los cuales esto puede ser problemático. “******Prop drilling******” es el problema por el que los componentes reciben ******props****** con el único propósito de servir como media para que ésta información llegue a los componentes hijos o más abajo en la jerarquía.

El problema de ****prop drilling**** no está directamente relacionado con Context, ya que ******************************************no todos los problemas****************************************** de prop drilling deben ser resueltos con Context.

# ¿CUÁNDO USAR CONTEXT?

Context es un **manejador de estado(los valores que tiene ciertos elementos en un momento dado)** por lo que su uso debe asociarse con almacenar la información que debe ser compartida por muchos componentes, introducir prop drilling o algún otro problema.

Algunos ejemplos son:

- **Autenticación de usuario.**
- **Theming.**
- **Manejo de distintos idiomas.**
- **Preferencias de moneda, zonas horarias…**

Si estás trabajando con información que afecta a distintos componentes, usar Context puede ayudar a compartir la información entre los componentes y que todos reciban la actualización correspondiente.

También se puede usar en secciones del árbol:

- **Un formulario para el que los controles deben compartir información.**
- **Un componente separado en distintos pasos para mostrar.**

Una aplicación puede tener y generalmente requiere más de un solo contexto.

# ¿CUÁNDO NO USAR CONTEXT?

El uso de Context tienen algunos detalles, los cuales son:

- **Complejidad**: Se cambia de un modelo donde la información fluye explícitamente a un modelo donde no es explícito dicho flujo de la información.
- **Acoplamiento**: Introduce dependencia entre los componentes.

Con Context la información ya no fluye en una sola vía, sino que puede ir en ambos sentidos, haciendo más complejo el código y su interpretación o entendimiento.

Si un elemento/componente está usando Context, no puede ser reciclado/reutilizado en partes del árbol que no tengan contexto, lo cual significa que los componentes operen en donde el contexto que necesitan esté disponible, produciendo dependencia y acoplamiento.

- En muchos casos **************************prop drilling************************** puede ser mejor que usar **************Context**************.
- En otros casos es mejor usar composición.

# ¿CÓMO USAR CONTEXT?

### Para implementarlo:

- Se debe importar la función “**************************createContext**************************” desde la librería de React.
    
    ```jsx
    **import { createContext } from "react";** //Se importa la función ****"****createContext****"****desde la librería de ""react, para crear un contexto dentro de un componente de React y comunicar información entre los componentes sin recorrer cada nivel del árbol de nuestros componentes
    ```
    
- Se declara una constante nombrada arbitrariamente especificando a qué contexto se hace referencia, a la cual se le asigna como valor, ejecutar la función importada “**createContext()**”.
    
    Ésta se puede exportar para poder ser utilizada en un componente externo.
    
    ```jsx
    **export** **const ThemeContext = createContext();** //Se exporta, la declaración de constante con valor asignado de, ejecutar la función para crear un contexto dentro de un componente de React
    ```
    

### Para utilizarlo:

- El resultado de llamar a ejecutar “**createContext()**” es un objeto que incluye la propiedad ****************Provider**************** que se debe de incluir en el árbol/JSX para indicar que todos los elementos que están dentro de dicho “****************Provider****************” pueden acceder a los valores almacenados en el contexto.
- Se declara como una **etiqueta HTML/componente React**, mediante el nombre declarado de la constante para el contexto, y acceder a su propiedad “****************Provider****************”.
    
    ```jsx
    import { useState, createContext } from "react"; //Se importan, la función hook "useState" para agregar estado a componentes funcionales, y la función "createContext" para crear un contexto que puede ser compartido entre componentes.
    import ColorPicker from "./ColorPicker"; //Se importa el componente "ColorPicker", desde, su ruta.
    
    **export const ThemeContext = createContext();** //Se exporta la declaración de constante con valor asignado de, ejecutar la función para crear un contexto compartido entre componentes, será utilizado para compartir y acceder al valor del color en diferentes componentes.
    
    export default function App() { //Se exporta como valor por defecto, la declaración de función que será un componente, será la raíz de la aplicación, la cual ejecuta el siguiente bloque.
        let [color, setColor] = useState("aquamarine"); //Declaración de variable la cual será un estado del componente, en la cual se utiliza la sintaxis de destructuración de arreglos, siendo el primer valor, el valor actual del estado el cual empieza siendo el valor por defecto enviado a "useState", y como segundo valor la función que actualizará el estado, dicha constante tiene valor asignado de, llamar a ejecutar la función importada para el estado del componente, la cual recibe como argumento para el valor por defecto del componente, el valor en cadena de texto de un color.
        return ( //Se retorna una estructura de JSX, el cual será el componente a ser renderizado, siendo colocado entre paréntesis.
            **<ThemeContext.Provider** value={[color, setColor]}**>** //Se coloca como etiqueta HTML/componente, el contexto declarado, accediendo a su propiedad "Provider", para indicar que todos los elementos pueden acceder a los valores almacenados en el contexto, y recibiendo la prop "value" para ser el valor del contexto con valor asignado de, dentro de llaves por ser código de JS, mediante la sintaxis de destructuración de arreglos, como primer valor, el valor actual del estado "color", y como segundo valor, la función de actualización para el valor de dicho estado, para que los componentes descendientes accedan y actualicen el valor del color.
                <div style={{ backgroundColor: color }}> //Etiqueta contenedora de bloque, la cual posee la propiedad de "estilo", con valor asignado dentro de llaves por ser código de JS, de un objeto que contendrá las propiedades CSS, la cual es, la propiedad de color de fondo, con valor, del valor actual del estado "color".
                    <h1>Hello</h1> //Etiqueta de título principal, contiene texto a ser mostrado.
                    <p>Lorem ipsum dolor sit amet consectetur elit :3</p> //Etiqueta de párrafo, contiene texto a ser mostrado.
                    <ColorPicker setColor={setColor}/> //Se ejecuta como etiqueta HTML/componente hijo, el componente "ColorPicker" impotado, el cual posee la propiedad "setColor" nombrada arbitrariamente para saber su función, con valor asignado dentro de llaves por ser código de JS, de la función de actualización del valor actual del estado "color", para así actualizar el valor de color del elemento "<div>" que posee la propiedad de color de fondo con valor del valor actual del estado "color".
                </div>
            **</ThemeContext.Provider>**
        );
    }
    ```
    
- Se define un valor para el contexto, mediante colocar la propiedad “****************value={[,]}****************” en “**<ThemeContext.Provider >**”, siendo mediante la sintaxis de destructuración de arreglos “****[]****”, el valor actual del estado correspondiente, y la función de actualización de dicho estado.
    
    ```jsx
    import { useState, createContext } from "react"; //Se importan, la función hook "useState" para agregar estado a componentes funcionales, y la función "createContext" para crear un contexto que puede ser compartido entre componentes.
    import ColorPicker from "./ColorPicker"; //Se importa el componente "ColorPicker", desde, su ruta.
    
    export const ThemeContext = createContext(); //Se exporta la declaración de constante con valor asignado de, ejecutar la función para crear un contexto compartido entre componentes, será utilizado para compartir y acceder al valor del color en diferentes componentes.
    
    export default function App() { //Se exporta como valor por defecto, la declaración de función que será un componente, será la raíz de la aplicación, la cual ejecuta el siguiente bloque.
        let **[color, setColor]** = useState("aquamarine"); //Declaración de variable la cual será un estado del componente, en la cual se utiliza la sintaxis de destructuración de arreglos, siendo el primer valor, el valor actual del estado el cual empieza siendo el valor por defecto enviado a "useState", y como segundo valor la función que actualizará el estado, dicha constante tiene valor asignado de, llamar a ejecutar la función importada para el estado del componente, la cual recibe como argumento para el valor por defecto del componente, el valor en cadena de texto de un color.
        return ( //Se retorna una estructura de JSX, el cual será el componente a ser renderizado, siendo colocado entre paréntesis.
            <ThemeContext.Provider **value={[color, setColor]}**> //Se coloca como etiqueta HTML/componente, el contexto declarado, accediendo a su propiedad "Provider", para indicar que todos los elementos pueden acceder a los valores almacenados en el contexto, y recibiendo la prop "value" para ser el valor del contexto con valor asignado de, dentro de llaves por ser código de JS, mediante la sintaxis de destructuración de arreglos, como primer valor, el valor actual del estado "color", y como segundo valor, la función de actualización para el valor de dicho estado, para que los componentes descendientes accedan y actualicen el valor del color.
                <div style={{ backgroundColor: color }}> //Etiqueta contenedora de bloque, la cual posee la propiedad de "estilo", con valor asignado dentro de llaves por ser código de JS, de un objeto que contendrá las propiedades CSS, la cual es, la propiedad de color de fondo, con valor, del valor actual del estado "color".
                    <h1>Hello</h1> //Etiqueta de título principal, contiene texto a ser mostrado.
                    <p>Lorem ipsum dolor sit amet consectetur elit :3</p> //Etiqueta de párrafo, contiene texto a ser mostrado.
                    <ColorPicker setColor={setColor}/> //Se ejecuta como etiqueta HTML/componente hijo, el componente "ColorPicker" impotado, el cual posee la propiedad "setColor" nombrada arbitrariamente para saber su función, con valor asignado dentro de llaves por ser código de JS, de la función de actualización del valor actual del estado "color", para así actualizar el valor de color del elemento "<div>" que posee la propiedad de color de fondo con valor del valor actual del estado "color".
                </div>
            </ThemeContext.Provider>
        );
    }
    ```
    

### Para utilizar el valor del contexto en algún componente externo:

- Se debe importar la función hook “**useContext**” desde la librería de React.
    
    ```jsx
    **import { useContext } from "react";** //Se importa la función hook "useContext" desde,la librería de "react", para acceder al contexto compartido.
    ```
    

- Se debe importar el “**createContext()**” declarado en el componente principal, el cual es el contexto necesario para el componente externo.
    
    ```jsx
    **import { ThemeContext } from "./App";** //Se importa el contexto declarado en el componente principal, para poder utilizar los valores de dicho contexto.
    ```
    
- Dentro del componente a utiliza el valor del contexto, se ejecuta el hook “**useContext()**” el cual recibe como argumento, el contexto importado desde el componente principal del cual se requiere obtener su información.
    
    Siendo que “**useContext()**” revisará si en la jerarquía hacía arriba encuentra en algún punto el  “**Provider**” para éste contexto, y de esta manera saber que si puede leer ésta información.
    
    **Para ello:**
    
    - Se declara una variable con la sintaxis de destructuración de arreglos, para **poder utilizar** el valor actual del estado correspondiente, y la función de actualización de dicho estado.
        
        ```jsx
        **let [color, setColor] = useContext(ThemeContext);** //Declaración de variable con valor asignado de, mediante la sintaxis de destructuración de arreglos para acceder a los valores declarados en el contexto, los cuales son el valor actual del estado "color" y su función de actualización, con valor asignado de, ejecutar el hook para acceder al contexto compartido, el cual recibe como argumento, el contexto importado.
        ```
        
- Lo que retorna el hook “**useContext()**” es aquello que se haya asignado en la propiedad “**value={}**” del componente “**<ThemeContext.Provider value={}>**”, siendo el valor mas actualizado de dicho contexto.
    
    Cuando se ejecuta la función de actualización del estado que se obtuvo mediante la destructuración, es que se actualiza el estado de dicha función de actualización, lo que a su vez actualiza el contexto correspondiente.
    
    ```jsx
    **import { useContext } from "react";** //Se importa la función hook "useContext" desde,la librería de "react", para acceder al contexto compartido.
    **import { ThemeContext } from "./App";** //Se importa el contexto declarado en el componente principal, desde, su ruta, para poder utilizar los valores de dicho contexto.
    import PropTypes from "prop-types"; //Se importa el módulo "PropTypes" para validar las propiedades, desde, la librería "prop-types".
    
    export default function ColorPicker() { //Se exporta como valor por defecto, la declaración de fución que será un componente para controlar un color de fondo de un componente, la cual ejecuta el siguiente bloque.
        **let [color, setColor] = useContext(ThemeContext);** //Declaración de variable con valor asignado de, mediante la sintaxis de destructuración de arreglos para acceder a los valores declarados en el contexto, los cuales son el valor actual del estado "color" y su función de actualización, con valor asignado de, ejecutar el hook para acceder al contexto compartido, el cual recibe como argumento, el contexto importado.
        return ( //Se retorna una estructura de JSX, el cual será el componente a ser renderizado, siendo colocado entre paréntesis.
            <div> //Etiqueta contenedora de bloque.
                <input  //Etiqueta de control/ingreso de datos, la cual posee la s siguientes propiedades.
                    type="color" //Propiedad de tipo, con valor para ser un selector de color.
                    value={**color**} //Propiedad de valor, con valor asignado dentro de llaves por se código de JS, de el valor actual del estado "color".
                    onChange={(e) => **setColor(e.target.value)}** //Propiedad manejadora del evento de cambio en éste input, con valor asignado dentro de llaves por ser código de JS, de una función de flecha callback, la cual recibe como argumento el evento ejecutado, y ejecutando, la función de actualización del estado "color", la cual recibe como argumento, del evento ejecutado, acceder al elemento que lo ejecutó, y acceder a su valor, para que así cada vez que cambie el valor de éste contról ese sea el nuevo valor actual del estado "color".
                />
            </div>
        );
    }
    
    ColorPicker.propTypes = { //De dicha función componente, se accede a su propiedad estática "propTypes" que es un objeto para especificar los tipos de datos esperados de las propiedades(****props****) de un componente y asegurarse de que sean utilizadas correctamente, el cual es obtenido de la librería "prop-types", y se reasigna su valor.
        setColor: PropTypes.func //Se establece que, la propiedad "name" debe, desde la librería "PropTypes", ser una función
    }
    ```