Introducción a React Hooks



Si lees Twitter, lo más probable es que sepas que Hooks es una nueva función React, pero puedes preguntar, ¿cómo podemos usarlos en la práctica ? En este artículo, le mostraremos algunos ejemplos del uso de ganchos.
Una de las ideas clave para entender es que los ganchos le permiten usar el estado y otras características de React sin escribir clases .

La motivación detrás de los ganchos.


Aunque la arquitectura orientada a componentes nos permite reutilizar la vista en nuestra aplicación, uno de los mayores problemas que enfrenta un desarrollador es cómo reutilizar la lógica basada en estado entre componentes . Cuando tenemos componentes que tienen una lógica de estado similar, no hay buenas soluciones para reutilizar componentes, y esto a veces puede conducir a la duplicación de la lógica en el constructor y los métodos del ciclo de vida.
Para resolver este problema, usualmente use:

  • Componentes de alto orden
  • renderizar accesorios

Pero ambos patrones tienen desventajas que pueden contribuir a la complejidad de la base del código.

Los ganchos tienen como objetivo resolver todos estos problemas, permitiéndole escribir componentes funcionales que tienen acceso a estado, contexto, métodos de ciclo de vida, ref, etc., sin escribir clases.

Ganchos en alfa


Antes de bucear, es importante mencionar que el desarrollo de la API de Hooks aún no está completo.

Además, la documentación oficial es muy buena, y recomendamos leerla también porque describe ampliamente la motivación detrás de la introducción de Hooks.
UPD El artículo original, cuya traducción está leyendo, fue escrito en un momento en que esta API estaba en pruebas alfa, en este momento React Hooks está oficialmente listo para usar. Los cambios irreversibles realizados en la versión (en comparación con alfa) se pueden encontrar al final del artículo o en las notas de la versión .

Cómo se relacionan los ganchos con las clases


Si está familiarizado con React, una de las mejores formas de comprender Hooks es ver cómo podemos reproducir el comportamiento que estamos acostumbrados a trabajar con las clases que usan Hooks.

Recuerde que al escribir clases de componentes, a menudo necesitamos:

  • Administrar estado
  • Utilice métodos de ciclo de vida como componentDidMount () y componentDidUpdate ()
  • Contexto de acceso (tipo de contexto estático)


Con React Hooks, podemos reproducir un comportamiento similar en componentes funcionales:

  • Para usar el estado de un componente use useState () hook
  • En lugar de utilizar métodos de ciclo de vida como componentDidMount () y componentDidUpdate (), use useEffect () hook.
  • En lugar de usar la propiedad estática contextType, use useContext () hook.

Se requiere la última versión de React para usar Hooks.


Puede comenzar con Hooks en este momento cambiando el valor de react y react-dom en su package.json a "next".



Ejemplo de gancho UseState ()


El estado es una parte integral de React. Nos permite declarar variables que contienen datos, que, a su vez, se utilizarán en nuestra aplicación. Usando clases, el estado generalmente se define de la siguiente manera:



Antes de Hooks, el estado generalmente se usaba solo en un componente, una clase, pero, como se mencionó anteriormente, Hooks también nos permite agregar estado a un componente funcional .
Veamos un ejemplo a continuación. Aquí construimos un interruptor retroiluminado que cambia de color según el valor del estado. Para esto usaremos hook useState ().
Aquí está el código completo (y un ejemplo ejecutable): veremos lo que sucede a continuación. Al hacer clic en la imagen, puede ver este ejemplo en CodeSandBox.



Nuestro componente es una función.


En el bloque de código anterior, comenzamos importando useState desde React. UseState es una nueva forma de aprovechar las posibilidades que this.state podría ofrecer.
Luego observe que este componente es una función, no una clase . Interesante!

Leer y escribir estado


Dentro de esta función, llamamos a useState para crear una variable en estado:



useState se usa para declarar una variable de estado y se puede inicializar con cualquier tipo de valor (a diferencia del estado en las clases, que debería ser un objeto).

Como se vio anteriormente, estamos utilizando la desestructuración en el valor de retorno de useState.
  • El primer valor, claro en este caso, es el estado actual (como this.state)
  • El segundo valor es la función utilizada para actualizar el valor de estado (primer valor) (como this.setState).

Luego creamos dos funciones, cada una de las cuales establece el estado en diferentes valores, 0 o 1.



Luego los aplicamos como controladores de eventos en los botones de la vista:



Estado de pistas de reacción


Cuando se presiona el botón "On", se llama a la función setOn, que llama a setLight (1). Llamar a setLight (1) actualiza el valor de luz para el próximo render . Esto puede parecer un poco mágico, pero React realiza un seguimiento del valor de esta variable y pasará un nuevo valor cuando este componente se vuelva a representar.
Luego usamos el estado actual ( luz ) para determinar si la lámpara debe estar encendida o no. Es decir, establecemos el color de relleno del SVG dependiendo del valor de la luz . Si la luz es 0 (apagado), fillColor está configurado en # 000000 (y si es 1 (encendido), fillColor está configurado en # ffbb73).

Estados múltiples


Aunque no hacemos esto en el ejemplo anterior, puede crear varios estados llamando a useState más de una vez. Por ejemplo:



NOTA
Hay algunas limitaciones para usar ganchos que debe tener en cuenta. Lo más importante, solo debe llamar a los ganchos en el nivel superior de su función. Consulte " Reglas de ganchos " para obtener más información.


Ejemplo de enlace UseEffect ()


UseEffect Hook le permite realizar efectos secundarios en componentes funcionales . Los efectos secundarios pueden incluir acceder a la API, actualizar el DOM, suscribirse a los controladores de eventos; todo lo que desea es que suceda una acción "imperativa".

Al usar el enlace useEffect (), React sabe que desea realizar una acción específica después de la representación.

Veamos un ejemplo a continuación. Usaremos useEffect () para llamar a la API y obtener una respuesta.



Este ejemplo de código usa useState y useEffect , y esto se debe a que queremos escribir el resultado de la llamada API al estado.



Recibir datos y actualizar estado


Para "usar el efecto", necesitamos poner nuestra acción en la función useEffect , es decir, pasamos el efecto "acción" como una función anónima, como el primer argumento para usarEffect .
En el ejemplo anterior, nos referimos a una API que devuelve una lista de nombres. Cuando la respuesta regresa, la convertimos a JSON y luego usamos setNames (datos) para establecer el estado.



Problemas de rendimiento al usar efectos



Sin embargo, hay algo más que decir sobre el uso de useEffect .

¡Lo primero que debe pensar es que, por defecto, se llamará a useEffect en cada render! La buena noticia es que no debemos preocuparnos por los datos obsoletos, pero la mala noticia es que probablemente no queramos hacer una solicitud HTTP para cada representación (como en este caso).

Puede omitir efectos utilizando el segundo argumento useEffect , como en este caso. El segundo argumento para usar Effect es una lista de variables que queremos "observar", y luego volveremos a ejecutar el efecto solo cuando cambie uno de estos valores.

En el ejemplo de código anterior, tenga en cuenta que estamos pasando una matriz vacía como segundo argumento. Somos nosotros quienes le decimos a React que solo queremos nombrar este efecto al montar el componente.

Para obtener más información sobre el rendimiento del efecto, consulte esta sección en documentos técnicos.

Además, al igual que la función useState, useEffect le permite usar varias instancias, lo que significa que puede tener múltiples funciones useEffect.

Ejemplo de enlace UseContext ()


Punto de contexto

El contexto en React es una forma para que un componente secundario acceda a un valor en el componente primario.

Para comprender la necesidad de contexto: al crear una aplicación React, a menudo necesita pasar valores desde la parte superior de su árbol React hacia abajo. Al no usar el contexto, pasa accesorios a través de componentes que no necesitan saber sobre ellos.

Pasar accesorios por el árbol de componentes "no relacionados" se llama cariñosamente perforación de accesorios.
React Context resuelve el problema de perforación de accesorios al permitirle compartir valores a través del árbol de componentes, con cualquier componente que solicite estos valores.

useContext () simplifica el uso del contexto

Con useContext Hook, usar el contexto es más fácil que nunca.

La función useContext () toma un objeto de contexto, que inicialmente se devuelve desde React.createContext () , y luego devuelve el valor de contexto actual. Veamos un ejemplo a continuación.



En el código anterior, el contexto de JediContext se crea usando React.createContext ().

Usamos JediContext.Provider en nuestro componente de la aplicación y establecemos el valor en "Luke" allí. Esto significa que cualquier componente que necesite acceder al contexto ahora podrá leer este valor.

Para leer este valor en la función Display (), llamamos a useContext, pasando el argumento JediContext.

Luego pasamos el objeto de contexto que obtuvimos de React.createContext, y automáticamente muestra el valor. Cuando se actualiza el valor del proveedor, este enlace funcionará automáticamente con el último valor de contexto.

Obtener un enlace al contexto en una aplicación más grande


Arriba, creamos JediContext dentro de ambos componentes, pero en una aplicación más grande, Display y App estarán en diferentes archivos. Por lo tanto, si tiene una situación similar, puede que se pregunte: "¿Cómo obtenemos un enlace a JediContext entre archivos?"

La respuesta es que necesita crear un nuevo archivo que exporte el JediContext .
Por ejemplo, puede tener un archivo context.js que contiene algo como esto:



y luego en App.js (y Display.js) deberías escribir:



Gracias Dave )

Ejemplo de gancho UseRef ()


Refs proporciona una forma de acceder a los elementos React creados en el método render ().
Si eres nuevo en React refs, puedes leer esta introducción a React refs .
La función useRef () devuelve un objeto ref.



useRef () y formularios con entrada


Veamos un ejemplo usando el gancho useRef ().



En el ejemplo anterior, usamos useRef () en combinación con useState () para representar el valor de entrada en la etiqueta p.

Ref se crea en la variable nameRef. Entonces la variable nameRef se puede usar en la entrada, dada como ref. Básicamente, esto significa que ahora se podrá acceder al contenido del campo de entrada mediante la ref.

El botón de envío en el código tiene un controlador de eventos onClick llamado submitButton. La función submitButton llama a setName (creado a través de useState).

Como ya hicimos con hookState, setName se usará para establecer el nombre del estado. Para extraer el nombre de la etiqueta de entrada, leemos el valor de nameRef.current.value.

Otra nota con respecto a useRef es que se puede usar más que el atributo ref.

Usando ganchos personalizados


Una de las mejores características de Hooks es que puedes compartir fácilmente la lógica entre múltiples componentes creando tu propio Hook.

En el siguiente ejemplo, crearemos un gancho setCounter () personalizado que nos permite rastrear el estado y proporcionar funciones de actualización de estado personalizadas.

Consulte también, este useCounter Hook de react-use y useCounter de Kent




En el bloque de código anterior, creamos una función useCounter que almacena la lógica de nuestro enlace.

¡Tenga en cuenta que useCounter puede usar otros ganchos! Comencemos creando un nuevo estado Hook a través de useState.

Luego definimos dos funciones auxiliares: incremento y decremento , que llaman a setCount y ajustan el conteo actual en consecuencia.

Finalmente, devolvemos los enlaces necesarios para interactuar con nuestro gancho.

P: ¿Qué sucede al devolver una matriz con un objeto?
R: Bueno, como la mayoría de las cosas en Hooks, las convenciones de API aún no están completas. Pero lo que hacemos aquí devuelve una matriz, donde:

  • El primer elemento es el valor actual del gancho.
  • El segundo elemento es un objeto que contiene las funciones utilizadas para interactuar con el gancho.

Esta convención le permite "cambiar el nombre" fácilmente del valor actual del gancho, como lo hacemos anteriormente con myCount .

Sin embargo, puede devolver lo que quiera de su gancho personalizado.

En el ejemplo anterior, usamos incrementos y decrementos como controladores onClick en nuestra opinión. Cuando el usuario presiona los botones, el contador se actualiza y se vuelve a mostrar (como myCount ) en la vista.

Escritura de pruebas para ganchos de reacción


Para escribir pruebas para ganchos, usaremos la biblioteca react-testing para pruebas.

react-testing-library es una solución muy ligera para probar componentes React. Es una extensión de react-dom y react-dom / test-utils . El uso de la biblioteca react-testing asegura que sus pruebas funcionen directamente con los nodos DOM.

Con los ganchos de prueba, no todo está claro todavía. Actualmente, no puede probar el gancho de forma aislada. En su lugar, debe conectar su gancho al componente y probar este componente.

Entonces, a continuación escribiremos pruebas para nuestros Hooks, interactuando con nuestros componentes y no directamente con Hooks. La buena noticia es que nuestras pruebas se verán como pruebas de React regulares.

Prueba del gancho useState ()


Veamos un ejemplo de pruebas de escritura para useState Hook. En el tutorial anterior, probamos más variaciones del ejemplo useState utilizado anteriormente. Escribiremos pruebas para asegurarnos de que presionar el botón "Off" establece el estado en 0 y presionar el botón "On" establece el estado en 1.



En el bloque de código anterior, comenzamos importando algunos ayudantes de la biblioteca react-testing y el componente bajo prueba.

  • render , esto ayudará a mostrar nuestro componente. Se representa en un contenedor que se agrega a document.body
  • getByTestId obtiene el elemento DOM por data-testid
  • fireEvent , esto se usa para "desencadenar" eventos DOM. Adjunta un controlador de eventos para documentar y procesar algunos eventos DOM a través de la delegación de eventos, por ejemplo. haciendo clic en un botón

Además, en la función de aprobación de prueba, establecemos los valores de variables para elementos con data-testid y sus valores que nos gustaría usar en la prueba. Con enlaces a elementos en el DOM, podemos usar el método fireEvent para simular un clic en un botón.

La prueba verifica que si se hace clic en onButton , el valor de estado se establece en 1, y cuando hace clic en offButton, el estado es 1.

Prueba del gancho useEffect ()


En este ejemplo, escribiremos pruebas para agregar un producto al carrito usando useEffect Hook. El número de elementos también se almacena en localStorage. El archivo index.js en CodeSandbox a continuación contiene la lógica real utilizada para agregar artículos al carrito.

Escribiremos pruebas para asegurarnos de que la actualización de la cantidad de artículos del carrito también se refleje en localStorage, e incluso si la página se vuelve a cargar, la cantidad de artículos del carrito sigue siendo la misma.



En la función que confirma la prueba, primero establecemos cartItem en localStorage en 0, lo que significa que el número de artículos de carrito es 0. Luego obtenemos el contenedor y el proceso de re - procesamiento desde el componente de la aplicación mediante la desestructuración. Rerender nos permite simular recargas de página.

Luego obtenemos los enlaces a los botones y la etiqueta p, que muestra el valor actual de la cesta y los establece en variables.

Una vez hecho esto, la prueba simula un clic en addButton y comprueba si el contador de la cesta actual es 1 y vuelve a cargar la página, después de lo cual si comprueba si localStorage , cartItem está configurado en 1. Luego simula un clic en resetButton y comprueba si el número actual de artículos del carrito está establecido en 0.

Prueba de gancho useRef ()


En este ejemplo, probaremos useRef Hook, y usaremos el ejemplo original useRef anterior como base para la prueba. UseRef se usa para obtener el valor del campo de entrada y luego establece el valor en estado. El archivo index.js en CodeSandbox a continuación contiene la lógica para ingresar un valor y enviarlo.



En la función que aprueba la prueba, establecemos las variables en el campo de entrada, una etiqueta p que muestra el valor de referencia actual y un botón de envío. También establecemos el valor que nos gustaría ingresar en el campo de entrada para la variable newName. Esto se usará para la verificación en la prueba.



El método fireEvent.change se usa para ingresar un valor en el campo de entrada, en cuyo caso se usa el nombre almacenado en la constante newName, después de lo cual se presiona el botón Enviar.

Luego, la prueba verifica si el valor de referencia después de presionar el botón coincide con el valor de newName .

Por último, debería ver "No se producen bloqueos de prueba, ¡felicidades!" mensaje en la consola.

Respuesta de la comunidad a los ganchos


Desde la introducción de React Hooks, la comunidad ha quedado encantada con esta característica, y hemos visto muchos ejemplos y ejemplos del uso de React Hooks. Estos son algunos de los principales:



Diferentes tipos de ganchos


Existen varios tipos de ganchos que puede comenzar a usar en su aplicación React. Se enumeran a continuación:

  • useState : nos permite escribir funciones puras con acceso al estado en ellas.
  • useEffect : nos permite realizar efectos secundarios. Los efectos secundarios pueden ser llamadas a la API, actualizar el DOM, suscribirse a controladores de eventos.
  • useContext : le permite escribir funciones puras con contexto en ellas.
  • useReducer : nos proporciona un enlace a un reductor similar a Redux
  • useRef : le permite escribir funciones puras que devuelven un objeto de referencia mutable.
  • useMemo - .
  • useCallback — Hook .
  • useImperativeMethods - , ref.
  • useMutationEffects — useEffect Hook , DOM-.
  • useLayoutEffect - DOM -.
  • hooks - .


hooks


Lo mejor de Hooks es que funcionan codo a codo con el código existente, por lo que puedes hacer cambios lentamente para implementar Hooks. Todo lo que tiene que hacer es actualizar React a una versión compatible con ganchos.

Sin embargo, los ganchos siguen siendo una característica experimental, y el equipo de React ha advertido repetidamente que la API se puede cambiar. Considera que estás advertido.
¿Qué significa la aparición de ganchos para las clases? Como informa el equipo React, las clases aún permanecen, son una gran parte de la base del código React, y lo más probable es que lo sean por algún tiempo.

. Facebook , , , , . React Hooks, —

API- Hooks , Hooks, , .

Recursos Adicionales


  • React React Hooks,
  • API .
  • RFC, ,


UPD
:
React 16.8 Hooks API. -:
— useMutationEffect.
— useImperativeMethods useImperativeHandle.
— useState useReducer Hooks.
— , useEffect/useMemo/useCallback Hooks.
— Object.is useState useReducer.
— Strict Mode (DEV-only).
— lazy initialization API useReducer Hook.
.

Source: https://habr.com/ru/post/es429712/


All Articles