ansango

Hooks ⚛️

Autor
avatar
Name
Anibal Santos
Publicado
Lectura
4 '
Hooks ⚛️

En este capítulo vamos a hablar acerca de los hooks en React.

¿Qué son los hooks?

Los hooks son funciones que enganchan el estado y el ciclo de vida de un componente. No funcionan con componentes de clases.

useState

import { useState } from 'react'
const CountButton = () => {
const [count, setCount] = useState(0)
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
)
}
  • useState: declara la variable estado. El argumento que recibe es el valor inicial del estado.
  • count: es la variable para leer el valor actual del estado.
  • setCount: es la función que actualiza el valor del estado.

useEffect

Incluye la lógica de métodos componentDidUpdate, componentDidMount y componentWillUnmount

import { useEffect } from 'react'
useEffect(() => {
// se ejecuta la lógica del mount y el update, como por ejemplo fetching data
})
import { useEffect } from 'react'
useEffect(() => {
// se ejecuta la lógica del mount y el update, como por ejemplo fetching data
return () => {
// se ejecuta la lógica del unmount (limpiar, cancelar timers, suscripciones)
}
}, [])
import { useEffect } from 'react'
const Component = (props) => {
useEffect(() => {
// la lógica es ejecutada cuando ALGUNA de las variables cambia
}, [arrOfDependency, values, props.id])
}

Essential hooks: useState & useEffect

import { useEffect, useState } from 'react'
const ComponentWithHooks = () => {
const [projectId, setProjectId] = useState(0)
const [versionId, setVersionId] = useState(0)
useEffect(() => {
getComments()
}, [])
useEffect(() => {
getGeneralData(projectId, versionId)
getIndicators(projectId, versionId)
}, [projectId, versionId])
}

Otros Hooks

useReducer

Se utiliza para realizar una gestión del estado avanzada. Es parecido al concepto de reducer en Redux, Vuex, NGRX.

Es una forma de ordenar un estado complejo.

const [state, dispatch] = useReducer(reducer, { count: initialCount })

useCallback

Nos memoriza una función, es una forma de cachear funciones, a no ser que cambie a o b, no se vuelve a ejecutar dicha función. Por lo tanto podemos utilizarlo si no queremos estar definiendo constantemente una función.

const memoizedCallback = useCallback(() => {
doSomething(a, b)
}, [a, b])

useMemo

Nos memoriza un valor, es una forma de cachear valores, a no ser que cambie a o b, no se vuelve a ejecutar la función. Es útil cuando tenemos por ejemplo un cálculo de algo costoso.

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b])

useRef

Genera referencias de elementos, variables, elementos del DOM... para tenerlos accesibles.

const refImg = useRef(initialValue);
<img ref={refImg}>

Cómo refactorizar componente de clase a componente funcional:

import { useEffect } from 'react'
const Header = (props) => {
useEffect(() => {
window.alert('mount')
}, [])
useEffect(() => {
// Realmente habría que hacerlo con un useRef en un custom hook
if (props.title !== 'React Training') {
window.alert('update')
}
}, [props.title])
return (
<header onClick={props.onClick}>
<h1>{props.title}</h1>
<nav>
<ul>
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
<li>Option 4</li>
</ul>
</nav>
</header>
)
}
const App = () => {
const [title, setTitle] = useState('React Training')
const handleHeaderClick = () => {
setTitle(`${title} Classes`)
}
return (
<div>
<Header title={title} handleClick={handleHeaderClick} />;
</div>
)
}

Realmente no es usual que tengamos el caso de componentDidMount y componentDidUpdate en useEffect, algo más aproximado a la vida real sería el siguiente ejemplo:

import { useEffect, useState } from 'react'
const getData = () =>
new Promise((res) =>
setTimeout(() => {
res({ title: 'New Title' })
}, 2000)
)
const Header = (props) => {
const [data, setData] = useState({ title: null })
useEffect(() => {
getData(props.title).then((res) => setData(res))
}, [props.title])
return (
<header onClick={props.onClick}>
<h1>{props.title}</h1>
<nav>
<ul>
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
<li>Option 4</li>
</ul>
</nav>
</header>
)
}
const App = () => {
const [title, setTitle] = useState('React Training')
const handleHeaderClick = () => {
setTitle(`${title} Classes`)
}
return (
<div>
<Header title={title} handleClick={handleHeaderClick} />;
</div>
)
}

Custom Hooks

Partiendo del ejemplo anterior vamos a ver un ejemplo de custom hook:

import { useEffect, useState } from 'react'
const getData = () =>
new Promise((res) =>
setTimeout(() => {
res({ title: 'New Title' })
}, 2000)
)
const useData = (tile) => {
const [data, setData] = useState({ title: null })
useEffect(() => {
getData(title).then((res) => setData(res))
}, [title])
return [data, setData]
}
const Header = (props) => {
const [data, setData] = useData(props.title)
return (
<header>
<h1 onClick={props.onClick}>{data.title}</h1>
<nav>
<ul>
<li onClick={() => setData({ title: 'Option 1' })}>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
<li>Option 4</li>
</ul>
</nav>
</header>
)
}
const App = () => {
const [title, setTitle] = useState('React Training')
const handleHeaderClick = () => {
setTitle(`${title} Classes`)
}
return (
<div>
<Header title={title} handleClick={handleHeaderClick} />;
</div>
)
}

Aplicar custom hooks nos permite reutilizar código y sacar algo de lógica de los componentes. Básicamente está compuesto por otros hooks:

const useData = (tile) => {
const [data, setData] = useState({ title: null })
useEffect(() => {
getData(title).then((res) => setData(res))
}, [title])
return [data, setData]
}

❤️ Espero que te haya gustado la entrada.

Puedes continuar leyendo el siguiente capítulo sobre Conceptos avanzados, volver al capítulo anterior de Class components, o volver al Índice.

Utilizo cookies para mejorar mi contenido. Al continuar utilizando este sitio, estás aceptando el uso que hago de las cookies.