React Hooks
React Hooks
Juan Correa
Este libro está a la venta en http://leanpub.com/react-hooks
Éste es un libro de Leanpub. Leanpub anima a los autores y publicadoras con el proceso de
publicación. Lean Publishing es el acto de publicar un libro en progreso usando herramientas
sencillas y muchas iteraciones para obtener retroalimentación del lector hasta conseguir el libro
adecuado.
Índice general
Esto es sólo una muestra introductoria para que veas como luce un hook. No te preocupes si este
ejemplo no hace sentido. Ya veremos en capítulos posteriores cada hook paso a paso :).
Conforme avances en estas páginas te darás cuenta del PODER de los hooks y los nuevos caminos
que se abren para ti al momento en que diseñas tus componentes.
¿Los React Hooks van a reemplazar los componentes de tipo clase?
No realmente. Un buen acierto de React es que los componentes de tipo clase van a seguir siendo
soportados, por lo que puedes tener la tranquilidad de que tu código fuente que las contenga va a
seguir funcionando.
Introduccion a los React Hooks 3
Lo cierto es que a partir de ahora puedes elegir crear componentes de tipo clase o tipo función según
las necesidades de la aplicación y de tus criterios como desarrollador.
Al momento de escribir este manual, hay un caso de uso en el que los componentes de tipo clase
pueden hacer algo que los hooks no pueden: el manejo de límite de errores (Error Boundaries).
Si no estás familiarizado con esto, es simplemente la capacidad de un componente de manejar un
error de ejecución y te provee acceso a actuar en consecuencia, como mostrando un mensaje y
canalizar el error en un servicio de informes como Sentry. Todo esto sin tirar la aplicación.
Los hooks nos proveen de una manera más limpia para manejar la misma lógica que nos permiten
manejar los ciclos de vida de una clase como veremos en los ejemplos de cada hook.
Ya que te beneficia tener código simple en vez de complejo, probablemente termines eligiendo los
hooks la mayoría de las veces.
Aunque ojo: aún con hooks puedes terminar con código complejo si sigues malas prácticas. Este
manual te va a guiar en las buenas prácticas para que saques el máximo provecho a los hooks.
¿Qué necesidades cubren los React Hooks?
Los hooks vienen para resolver los siguientes problemas:
Reusar lógica entre componentes: La manera de reusar lógica antes de los hooks era por medio de
patrones o técnicas como los render props y los componentes de orden superior (HOC por sus siglas
en inglés).
El problema de esto es que la jerarquía de componentes tiende a terminar siendo un árbol complejo
de envolvedores (wrapper hell).
Veremos en un apartado posterior cómo puedes crear tus propios hooks, de modo que ahora podrás
reusar lógica entre componentes de una manera más limpia y sin necesidad de modificar la jerarquía
de los mismos.
Componentes complejos: En este contexto, un componente complejo es aquel que para funcionar
termina ejecutando varias sentencias de código que pueden estar o no relacionadas en los mismos
métodos de ciclos de vida de un componente.
Por ejemplo: puede que cuando se monte el componente, en el método componentDidMount,
consumas una api y en ese mismo método inicialices una o varias subscripciones de eventos del
navegador (o de algo diferente a la api).
Lo anterior ocasiona que tengamos lógica diferente mezclada en el mismo lugar.
El inconveniente de esto es que el código se hace difícil de leer y por lo tanto da pie a los errores
humanos.
Ahora pasemos a la acción y veamos cada uno de los hooks, cómo, por qué y en qué contextos
usarlos.
Te veo en el siguiente capítulo :)
Mucho mejor! el componente es mas simple, mas limpio y con el mismo poder del manejo de estado
de React :D.
Codigo fuente para ejecutar y editar aqui².
El hook useState nos retorna siempre un array con dos elementos.
Destructuracion de array en el hook useState
La sintaxis que vemos con los corchetes no es de React sino de ES6 y es llamada destructuracion.
En la posicion cero del array nos retorna la variable de estado y la posicion uno nos retorna una
funcion que nos sirve para actualizar la variable de estado.
Por lo tanto, lo siguiente es igualmente valido para Javascript.
declaracion de variables de estado sin destructurar
Como puedes ver, es mas limpio usar la destructuracion por lo que siempre veras ejemplos de ese
modo.
²https://codesandbox.io/s/use-state-5u0tf?file=/src/App.js
Y al ser destruturado, podemos nombrar las dos variables de la manera que convenga mejor a
nuestros intereses.
Lo recomendado es que sean nombres con significado, que indiquen cual es su proposito.
Ya que la segunda variable es una funcion que actualiza el estado, en todos los ejemplos vas a
encontrar que inicia con “set” y termina con el nombre de la variable de estado.
El hook useState recibe por parametro el valor inicial de la variable de estado
A diferencia del estado en un componente de tipo clase, la variable de estado usando este hook no
tiene que ser necesariamente un objeto.
Nuestro estado puede ser una variable de los siguientes tipos:
• String.
• Boolean.
• Number.
• Float.
• Null.
• Undefined.
• Object.
• Array.
Para valores de estado iniciales que sean resultado de un calculo costoso, puedes pasar como valor
inicial una funcion que retorne dicho valor calculado.
Ejemplo de valor inicial usando una funcion
Ten en cuenta que los valores iniciales del estado se ejecutan solo una vez y es cuando se monta el
componente
Te recomiendo que trates de mantener tus variables de estado lo mas simples posibles y separarlas
en diferentes variables cada que puedas.
Sin embargo, a veces vas a necesitar usar arrays u objetos como variables de estado, en esos casos
te recomiendo que trates de mantenerlos lo mas planos posibles.
Para estructuras mas complejas (un objeto de objetos, un array de objetos que tienen objetos, etc);
lo recomendable es usar el hook useRedux como veremos en su capitulo correspondiente.
La razon de por que no debemos mutar nuestro array con metodos como push, pop, etc, es porque
React no detecta esos cambios y no hara un re renderizado.
Esta sintaxis setTags([...tags, 'new value']); es propia de ES6 y se llama spread operator.
Lo que hacemos con ella es crear un NUEVO array cuyo contenido va a ser igual a todo lo que tenga
el array tags y aparte, un nuevo valor que es 'new value'.
Lo mismo aplica si tienes un array de objetos en vez de un array de cadenas: setTags([...tags, {
value:'new value'}]) (asumiendo que tags es un array de objetos).
Ahora bien, un array puede contener objetos en vez de valores primitivos como cadenas. Veamos el
ejemplo de como actualizar cuando es un array de objetos.
13 setTags(tagsUpdated);
14 };
Nota que tambien estamos usando el spread operator para crear un nuevo objeto con las
propiedades correspondientes.
En el segundo ejemplo estamos modificando la propiedad name de manera dinamica usando
[property]: "Juanito Banana" donde property = 'name';.
Para editar una propiedad es exactamente igual a como cuando le asignamos un valor.
• Peticiones de datos.
• Establecimiento de suscripciones.
• Actualizaciones manuales del DOM.
Esto ya se viene haciendo en React en los componentes de tipo clase por medio de los ciclos de vida.
Pues bien, estos efectos secundarios ahora también los podemos hacer en componentes funcionales.
La manera en que luce el hook useEffect es la siguiente.
Ejemplo del hook useEffect
1 const MyComponent = () => {
2 useEffect(() => {
3 console.log('useEffect ejecutado');
4 })
5
6 return ':)';
7 }
Caracteristicas de useEffect
1. Recibe dos parámetros: el primero una función y el segundo un array cuyos valores serán
variables de las que depende nuestro efecto (este array es opcional).
2. Se ejecuta en cada renderizado incluyendo el primero.
3. Puedes usar más de un useEffect dentro de un componente.
4. Está diseñado para que si la función que pasamos por parámetro retorna a su vez otra función,
React va a ejecutar dicha función cuando se desmonte el componente.
Hook de efectos secundarios useEffect 13
Ejemplos de useEffect
Esto es lo mínimo necesario que necesitas saber para comenzar a usar useEffect.
Pero para ponerla más fácil, vamos a ver ejemplos de casos prácticos del mundo real en el uso de
este hook.
9 }
10
11 render() {
12 return this.state.data.map(
13 ({ label }) => (<p>{label}</p>)
14 );
15 }
16 }
Nada fuera de lo común. Estamos haciendo una llamada a la api cada vez que el user id cambie.
Ahora veamos su equivalente en un componente funcional.
Como puedes ver, sólo hemos pasado la variable userId como dependencia dentro del array del
useEffect.
Esto significa que nuestro efecto se va a ejecutar al montarse el componente y cada vez que la
variable userId cambie, logrando así nuestro objetivo.
El código anterior lo puedes ejecutar y editar en este link.³
³https://codesandbox.io/s/use-effect-go50j?file=/src/App.js:649-881
Ejemplo de suscripción
• El hook useEffect recibe dos parámetros: una función que React ejecutará en cada renderizado
y un array de dependencias como opcional.
• Para emular componentDidMount pasa un array vacío.
• Para emular componentWillUnmount retorna una función con la lógica que quieres correr
cuando se desmonte el componente, usado comúnmente en las suscripciones.
• Para emular componentDidUpdate pasa las variables dependientes del estado en el array de
dependencias.
• Puedes usar más de un useEffect en el mismo componente.
Este ejemplo es sólo para que te familiarices con la manera en que se define este hook.
Antes de continuar es importante tener en cuenta ciertos detalles.
Cuando un prop cambia, se ejecuta un re render. ¿Cierto?
Pues bien, este hook es útil en el escenario en el que pasas funciones por props a componentes
hijos.
Memorizar una función ayuda a evitar re renders innecesarios debido a la manera en que funciona
Javascript como lenguaje.
Igualdad referencial en Javascript
Nota: las funciones para actualizar el estado que retorna useState tienen garantía de que serán
estables todo el tiempo, por lo que nos podemos despreocupar de ellas.
Al usar un callback memorizado logramos que no se vuelva a definir ese callback en cada render a
menos que alguna de sus dependencias cambie.
Si te suena confuso no te preocupes que para eso está este ebook :)
Vamos a ver un ejemplo a continuación, sigue leyendo :D
lista de alimentos
1 const food = [
2 { id: 1, name: "pizza" },
3 { id: 2, name: "hamburger" },
4 { id: 3, name: "hot-dog" },
5 { id: 4, name: "tacos" },
6 { id: 5, name: "pizza again :)" }
7 ];
⁴https://es.reactjs.org/docs/react-api.html#reactmemo
FoodContainer
FoodList
1 const FoodList = ({ foodList, removeItem }) => {
2 console.log("FoodList rendered");
3 return (
4 <ul>
5 {foodList.map((item) => (
6 <FoodItem
7 key={item.id}
8 item={item}
9 removeItem={removeItem}
10 />
11 ))}
12 </ul>
13 );
14 };
FoodItem
1 const FoodItem = ({ item, removeItem }) => {
2 console.log("FoodItem rendered");
3 return (
4 <>
5 <li>{item.name}</li>
6 <button
7 onClick={() => removeItem(item.id)}>
8 Remove :(
9 </button>
10 </>
11 );
12 };
Escribe en el input text y oberva los console logs desde la herramienta donde se ejecuta el código,
no de la consola de tu navegador.
En este link⁵ lo puedes ejecutar.
Como puedes ver, se hacen re renders en los componentes debido a que cambia la variable de
estado que usmamos para controlar el input, aunque realmente no cambien los valores de la lista de
alimentos.
El primer cambio que haremos es envolver los componentes FooList y FoodItem con React.memo
para que no se re rendericen dados los mismos props.
Nota: hacemos import de memo del modo: import React, { memo } from 'react';
⁵https://codesandbox.io/s/usecallback-9l0do
Dentro de FoodContainer
Usando en React.memo y el hook useCallback ahora hemos logrado optimizar los re renderizados
de este ejemplo.
A decir verdad, este es un ejemplo semi forzado porque la estructura de los componentes es candidata
a ser re factorizada para no tener la necesidad de pasar todos los props en el árbol de componentes.
Pero he querido hacerlo de este modo para poder ilustrar el ejemplo lo más fácil posible.
Es especialmente útil cuando el valor a memorizar es producto de un cálculo que consume “mucha”
memoria y procesamiento.
Ya que “mucha” tiende a ser subjetivo, considera la complejidad de un cálculo (o un algoritmo) en
base a lo siguiente:
• Constant: O(1)
• Logarithmic: O(log n)
• Linear: O(n)
• Linearithmic: O(n log n)
• Quadratic: O(n²)
• Expontential: O(2^n)
• Factorial: O(n!)
Un ejemplo clásico de una función que tenga una complejidad cuadrática (O(n²)) es cuando tienes
un ciclo dentro de otro ciclo.
functión de complejidad cuadrática
La pregunta es: ¿Cuántas veces se ejecutará el código dentro del segundo for si pasamos un
array con 10,000 elementos?
La respuesta es: 10,000 al cuadrado.
Ahora imagina que tienes algo como esto en un componente:
Prueba ejecutar lo anterior dando click aquí⁶ y observa la consola de la plataforma (no la de tu
navegador).
Probablemente no tengas problemas en un inicio dependiendo de lo que necesites lograr en tu
componente.
Puede que en un inicio no tengas muchos valores en tu array.
Incluso puede que logres optimizar la complejidad de ese algoritmo usando otra estructura de datos
como un diccionario o una tabla hash.
Pero si quieres una solución basado en lo que tiene React, en este caso el hook useMemo viene como
anillo al dedo.
¿Ya probaste el código⁷ anterior? Si no lo has hecho, te animo a que lo hagas porque ahora vamos a
ver la manera de optimizarlo con useMemo.
⁶https://codesandbox.io/s/usememo-rb185?file=/src/App.js
⁷https://codesandbox.io/s/usememo-rb185?file=/src/App.js
Así de simple. Sólo cambiando una línea de código hemos logrado hacer una optimiación de algo
que potencialmente puede afectar el performance de nuestra aplicación.
Prueba el código actualizado dando click aquí⁸.
No podemos hacer ejemplos de equivalencia entre estos elementos porque sería como comparar
peras con manzanas.
Lo que podemos hacer es observar cómo funcionan cada uno de ellos y es lo que vamos a hacer.
Para quien no esté familiarizado, PureComponent es parecido a Component que usamos para definir
componentes de tipo clase (ambos exportados en el import de React).
PureComponent es usado para componentes que al tener los mismos props y state, renderiza el
mismo resultado.
Implementa shouldComponentUpdate internamente, por lo que dados los mismos props y state, el
componente va a renderizar el mismo output.
Considera lo siguiente:
⁸https://codesandbox.io/s/usememo-aplicado-9otsj?file=/src/App.js:437-605
Este es un componente que sólo renderiza un elemento visual, no tiene lógica de llamada a api ni
nada por el estilo.
En este caso es conveniente usar PureComponent debido a que nos ahorra hacer la comparación
manualmente en si debe o no renderizar.
Su equivalente en Component usando shouldComponentUpdate es:
Aunque sigue siendo preferible usar PureComponent, no sólo por ahorrarnos líneas de código
sino por la propia recomendación de la (documentación en React)[https://es.reactjs.org/docs/react-
api.html#reactpurecomponent].
En esta solución basta con crear un componente de tipo clase con PureComponent y React hace todo
el trabajo por nosotros.
El HOC React.memo nos permite optimizar los renderizados sólo cuando los props cambian.
Consideremos el componente Title en forma de componente funcional.
Con esto hemos cubierto gran parte del tema para hacer optimizaciones en componentes en React.
Si aún no has leído el capítulo de useCallback te recomiendo que lo hagas para tener un
complemento de este capítulo.
Si ya lo leíste, ahora te invito a que pasemos al siguiente :D
1 {
2 foo: {
3 faa: {
4 test: [],
5 testB: ''
6 }
7 },
8 fee: [],
9 fii: {
10 testC: [],
11 testD: {}
12 }
13 }
En caso de que requieras un estado como el ejemplo anterior y no sea viable dividirlo usando
diferentes useState, lo recomendado es que uses useReducer.
¿Y cómo luce este hook?
Hook para estados complejos useReducer 31
Donde reducer es simplemente una función de Javascript que actualiza el estado, initialArg es el
estado inicial e init es una función opcional para también definir el estado inicial.
Este hook devuelve un array donde en la posición cero es el estado y en la posición uno es un
dispatch que es una función que usaremos para actualizar el estado.
Veamos más sobre el hook useReducer haciendo una comparación con redux y ejemplos sobre su
uso en los siguientes apartados.
1 const state = [
2 {
3 id: 1,
4 name: "Terminar de leer el capítulo de useReducer",
5 isCompleted: false
6 }
7 ];
Un array de objetos planos en el que cada objeto tendrá un id para identificarlo (podríamos usar el
índice del array pero no es lo común en aplicaciones reales), un name y un booleano isCompleted
que usaremos para marcar como completado o no completado.
Ahora hagamos nuestro reducer incluyendo la lógica necesaria para agregar un nuevo elemento de
nuestro TODO solamente de momento.
Reducer con lógica para agregar un TODO
Como es común, el reducer recibe el state y action. Estos valores serán pasados internamente por
useReducer.
Lo que nos debemos preocupar aquí es en colocar la lógica para actualizar el estado, cosa que
hacemos en el primer if.
Asumimos que tendremos un action.type igual a "ADD_TODO" y cuando lo recibamos vamos a
retornar el nuevo estado.
Para retornar el nuevo estado, vamos a usar el spread operator para crear un nuevo array agregando
todos los valores actuales de state, ya que state es un array.
Después agregamos el nuevo objeto con el id (usamos una biblioteca llamada uuid para que nos
genere los id únicos), el name que proviene de action.payload e isCompleted como false por default.
Ahora vamos a agregar la lógica para actualizar isCompleted de un elemento del TODO en particular.
Veremos únicamente la parte correspondiente dentro del reducer.
Esta lógica es muy diferente a la de agregar. No hacemos spread ni nada por el estilo.
Primero obtenemos el id del elemento a actualizar por medio de action.payload, después creamos
el nuevo estado por medio de state.map (.map retorna un nuevo array).
Dentro de .map está la parte importante.
Lo que hacemos aquí es comparar elemento por elemento para saber si el elemento de la lista coincide
con el id que nos interesa actualizar.
Si coincide, retornamos todo lo que contenga ese elemento de la lista y su propiedad isCompleted le
asignamos el valor contrario que tenga en ese momento.
Ejemplo:
1 // Si...
2 singleTodo.isCompleted = true
3
4 // Entonces...
5 !singleTodo.isCompleted // igual a false
6
7 // y viceversa
8
9 // Si...
10 singleTodo.isCompleted = false
11
12 // Entonces...
13 !singleTodo.isCompleted // igual a true
Ahora que tenemos estos elementos definidos, pasemos a crear nuestro componente :)
Tenemos el input para escribir el nuevo TODO y lo controlamos con un estado usando useState.
El listado está “hardcodeado” sólo para tener una idea de cómo mostraremos los elementos.
Ahora pasemos a agregar el useReducer :).
Y modificamos la parte del render para que muestre los valores de nuestro state. Recuerda que
pusimos un valor inicial en las cosas por hacer, por lo que será lo que se renderice en la lista.
1 <ul>
2 {
3 state.map(({ name, isCompleted, id }) => {
4 const style = {
5 textDecoration: isCompleted
6 ? "line-through" : "inherit"
7 };
8
9 return (
10 <li key={id} style={style}>
11 {name}
12 </li>
13 );
14 })
15 }
16 </ul>
Ahora vamos a colocar la lógica para que al dar click en el botón “Agregar”, nos agregue el nuevo
elemento en nuestro estado.
Ejecutamos el dispatch para actualizar el estado. Le pasamos el type y el payload necesarios como
se ve en el ejemplo.
Al final, reseteamos el valor de todoText para limpiar el contenido del input.
Por último, vamos a agregar la capacidad de marcar un elemento como completado o no completado
al dar click a un elemento del listado.
23 return (
24 <>
25 <p>
26 Nuevo TODO:
27 <input
28 type="text"
29 value={todoText}
30 onChange={handleChange}
31 />
32 <button onClick={handleClick}>Agregar</button>
33 </p>
34
35 <h2>Listado</h2>
36
37 <ul>
38 {state.map(({ name, isCompleted, id }) => {
39 const style = {
40 textDecoration: isCompleted
41 ? "line-through" : "inherit"
42 };
43
44 return (
45 <li
46 key={id}
47 style={style}
48 onClick={() => handleToggle(id)}
49 >
50 {name}
51 </li>
52 );
53 })}
54 </ul>
55 </>
56 );
57 };
• useReducer es un hook de React para actualizar un estado interno por medio de una función
llamada reducer.
• redux es una arquitectura que nos permite abstraer el manejo de un estado global en una
aplicación.
Redux es algo más complejo que abarca el nivel de decisiones de arquitectura de una aplicación,
siendo react-redux una biblioteca que nos permite integrarlo fácilmente en React.
La confusión puede caer en el uso de funciones llamadas reducers que son usadas como una parte
del funcionamiento de redux.
Espero que este capítulo te haya dado luces para que puedas comenzar a implementar este hook en
tus desarrollos cuando lo consideres necesario.
Te veo en el siguiente capítulo.
Para quien no esté familiarizado, Context nos permite comunicar props en un árbol de componentes
sin necesidad de pasarlos manualmente a través de props.
Algunos ejemplos de cuándo utilizar Context son:
Pero no es limitado a los ejemplos anteriores. Puedes aplicar Context a las necesidades de tu
aplicación según tu criterio.
En otras palabras, no es obligatorio que Context maneje un “estado global” de la aplicación: Puede
abarcar sólo una parte del estado si lo deseas.
A continuación vamos a ver ejemplos y comparaciones de cómo utilizar este hook para que puedas
aprovechar todo su potencial.
1 // theme-context.js
2
3 export const themes = {
4 light: {
5 color: "#555555",
6 background: "#eeeeee"
7 },
8 dark: {
9 color: "#eeeeee",
10 background: "#222222"
11 },
12 vaporwave: {
13 color: "#ffffff",
14 background: "#ff71ce"
15 }
16 };
17
18 export const ThemeContext = React.createContext(themes.light);
En este caso tenemos un objeto para representar temas diferentes que podemos usar en nuestra UI.
El tema por defecto es themes.light que es pasado por parámetro a createContext.
Ahora necesitamos proveer este context a nuestro árbol de componentes:
Proveer Context
1 export default function App() {
2 const [currentTheme, setCurrentTheme] =
3 useState(themes.light);
4
5 return (
6 <div className="App">
7 <h1>React Context</h1>
8
9 <ThemeContext.Provider value={currentTheme}>
10 <MyButton>Hello World!</MyButton>
11 </ThemeContext.Provider>
12 </div>
13 );
14 }
Estamos creando una variable de estado con useState para obtener el valor actual del tema.
Usamos ThemeContext.Provider value={currentTheme} para asignar el context y a partir de aquí,
todo el árbol de componentes hijos van a poder tener acceso a context si lo desean.
20 );
21 }
Con esto ya funciona pero por lo común vas a tener la necesidad de modificar el context desde un
componente hijo.
Para eso podemos modificar nuestro context para proveer su valor y además una función que sirva
para modificar su valor.
Primero modificamos nuestro context:
25 </MyButton>
26
27 {/* Nuevo Boton sin onClick */}
28 <MyButton>Light Theme</MyButton>
29 </ThemeContext.Provider>
30 </div>
31 );
32 }
En el componente MyButton vamos a hacer que si no recibe el prop de onClick, pondremos por
default updateTheme que obtenemos de ThemeContext:
Con esto ya estamos actualizando context desde un componente hijo o de manera directa en el
componente donde hacemos el provider.
Ahora vamos a hacer una nueva versión del código anterior para hacer uso de useContext y puedas
apreciar las diferencias.
La definición de ThemeContext no necesitamos modificarla, ni el Provider.
Lo que nos va a servir useContext es para poder acceder al valor de un context en un componente
funcional.
Veamos el refactor:
Ejemplo de useContext
1 const MyNewButton = (props) => {
2 const { theme, updateTheme } = useContext(ThemeContext);
3
4 const style = {
5 backgroundColor: theme.background,
6 color: theme.color,
7 border: "1px solid",
8 borderRadius: 5
9 };
10
11 const updateLightTheme = () => {
12 updateTheme(themes.light);
13 };
14
15 const onClick = props.handleClick || updateLightTheme;
16
17 return <button onClick={onClick} {...props} style={style} />;
18 };
Como puedes ver, lo único que cambia es que ahora podemos obtener nuestro valor de context
usando const { theme, updateTheme } = useContext(ThemeContext);.
Con esto cubrimos el tema de Context en sí mismo y el hook useContext.
Este hook nos retorna un objeto con una propiedad current que es mutable y cuyo valor persiste
durante los renderizados y ciclo de vida del componente.
Un caso de uso es usar referencias al DOM o a componentes de React.
Por ejemplo, cuando queremos hacer que un input tenga un auto focus al montarse.
Primero vamos a hacer el ejemplo con un componente de tipo clase y posteriormente la versión con
useRef.
16 // code
17 }
18 }
El hook useRef también nos sirve para tener referencias a cualquier valor.
De este modo, podemos emular variables de instancia:
Ejemplo de reactjs.org
1 function Timer() {
2 const intervalRef = useRef();
3
4 useEffect(() => {
5 const id = setInterval(() => {
6 // ...
7 });
8 intervalRef.current = id;
9 return () => {
10 clearInterval(intervalRef.current);
11 };
12 });
13
14 // ...
15 }
• Introducción a MERN¹¹. Crea una mini app usando uno de los stacks de Javascript más
populares usando MongoDB, Express, React y Node. Es una lista de vídeos gratuita.
• Patrones Avanzados en React JS: Crea componentes realmente reutilizables¹². Puedes leerlo
gratis si tienes la suscripción de Kindle Unlimited.
• Entra al sitio web de Developero¹³ para poder seguir más contenidos como este :)
Por último, quiero pedirte un favor. Si tienes posibilidad de dejar tu review y valoración de este
ebook gratuito, te lo voy a agradecer mucho :D
¹¹https://www.youtube.com/watch?v=p9RfYt6PGRc&list=PLkr7dGY4D2sOFts538pghxWaabulH2kMU&index=1&ab_channel=
Developero
¹²https://amzn.to/2Gos5A8
¹³https://developero.io/