Guia Completo dos Hooks do React
- #React
E aí, desenvolvedor! Vamos explorar todos os Hooks do React? Eles são uma adição incrível ao React 16.8 e permitem que você use o state e outros recursos do React sem escrever uma classe. Vamos explorar cada um dos Hooks e como usá-los.
useState
O useState é o Hook que nos permite adicionar o state do React a componentes funcionais.
import React, { useState } from 'react';
function Contador() {
const [count, setCount] = useState(0);
return (
<div>
<p>Você clicou {count} vezes</p>
<button onClick={() => setCount(count + 1)}>
Clique aqui
</button>
</div>
);
}
Neste exemplo, useState retorna um par: o valor do estado atual (count) e uma função que permite atualizá-lo (setCount).
O hook useState no React é comumente usado para:
- Gerenciamento de Estado Local: Permite adicionar estado reativo a componentes funcionais.
- Atualização de Estado: Fornece uma função para atualizar o estado, desencadeando uma nova renderização com o estado atualizado.
- Preservação de Estado: Preserva o estado entre as renderizações do componente.
- Inicialização de Estado: Pode ser inicializado com um valor padrão no momento da criação.
---
useEffect
O useEffect permite realizar efeitos colaterais em componentes funcionais. Ele é uma representação dos métodos componentDidMount, componentDidUpdate, e componentWillUnmount.
import React, { useState, useEffect } from 'react';
function Exemplo() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `Você clicou ${count} vezes`;
});
return (
<div>
<p>Você clicou {count} vezes</p>
<button onClick={() => setCount(count + 1)}>
Clique aqui
</button>
</div>
);
}
Neste exemplo, o useEffect atualiza o título do documento após a renderização do React.
O hook useEffect no React é comumente usado para:
- Sincronizar um componente com um sistema externo.
- Modificar o DOM.
- Fazer solicitações HTTP, como buscar dados de uma API.
- Adicionar event listeners.
- Substituir os ciclos de vida componentDidMount, componentWillUnmount e componentDidUpdate em componentes de classe.
- Controlar quando um efeito deve ser executado, por exemplo, apenas quando o componente é montado, quando determinado estado é atualizado, ou a cada renderização.
---
useContext
O useContext aceita um objeto de contexto (o valor retornado de React.createContext) e retorna o valor de contexto atual.
import React, { useContext } from 'react';
const ThemeContext = React.createContext('light');
function Exemplo() {
const theme = useContext(ThemeContext);
return <div>{theme}</div>;
}
Neste exemplo, o useContext permite que você leia o contexto atual sem precisar usar um Consumer.
O hook useContext no React é comumente usado para:
- Compartilhar propriedades comuns entre componentes, evitando a necessidade de passar muitos props duplicados.
- Compartilhar um tema entre componentes, como um tema dark e light.
- Acessar dados do usuário em vários componentes.
- Gerenciamento de idioma.
- Autenticação, permitindo que os componentes filho acessem e alterem o status de autenticação.
- Evitar a passagem manual de informações por todos os componentes intermediários.
---
useReducer
O useReducer é geralmente preferível ao useState quando você tem lógica de estado complexa que envolve vários sub-valores. Ele também permite que você otimize componentes para desempenho em alguns casos, evitando novas capturas.
import React, { useReducer } from 'react';
const initialState = {count: 0};
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}
Neste exemplo, useReducer é usado para gerenciar o estado do contador.
O hook useReducer no React é comumente usado para:
- Gerenciar estados complexos em componentes, similar ao reducer do Redux.
- Compartilhar estados entre vários componentes.
- Gerenciar estados que dependem de valores anteriores, pois o useReducer só requer que você forneça o próximo estado.
- Implementar contadores simples.
- Aplicar em listas de tarefas.
- Utilizar em formulários de Nome/E-mail.
- Criar um formulário de busca.
---
useCallback
useCallback retorna uma versão memorizada do callback que só muda se uma das dependências tiver mudado. Isso é útil quando se passam callbacks para componentes otimizados que dependem de igualdade de referência para evitar renderizações desnecessárias.
import React, { useState, useCallback } from 'react';
function App() {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount(count + 1);
}, [count]);
return (
<div>
Count: {count}
<button onClick={increment}>Increase</button>
</div>
);
}
Neste exemplo, useCallback é usado para memorizar o callback increment.
O hook useCallback no React é comumente usado para:
- Gerenciar funções complexas: Evita a recriação de funções a cada renderização, economizando recursos.
- Melhorar a performance: Evita ciclos de atualização de componentes indesejados.
- Implementar funções de manipulação de eventos: Como manipuladores de cliques para botões.
- Filtrar listas: Útil quando você tem uma lista e pretende realizar uma busca instantânea nos itens dessa lista.
- Trabalhar em conjunto com outros hooks: Como o useMemo, para armazenar um valor computado.
---
useMemo
useMemo retorna um valor memorizado.
import React, { useMemo } from 'react';
function App() {
const value = useMemo(() => computeExpensiveValue(a, b), [a, b]);
return <div>{value}</div>;
}
Neste exemplo, useMemo é usado para memorizar o valor retornado pela função computeExpensiveValue.
O hook useMemo no React é comumente usado para:
- Otimizar o desempenho: Memoriza o resultado de funções intensivas em recursos, evitando recálculos desnecessários.
- Formatar dados: Útil quando você precisa formatar dados antes de renderizá-los2.
- Filtrar dados: Pode ser usado para criar uma lista filtrada de itens a partir de uma lista existente.
- Ordenar dados: Ajuda a otimizar a ordenação de listas grandes.
- Realizar cálculos complexos: Útil para memorizar o resultado de cálculos complexos.
- Trabalhar em conjunto com outros hooks: Como o useCallback, para armazenar um valor computado.
---
useRef
useRef retorna um objeto ref mutável cuja propriedade .current é inicializada com o argumento passado (initialValue). O objeto retornado persistirá durante todo o ciclo de vida do componente.
import React, { useRef } from 'react';
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
Neste exemplo, useRef é usado para manter a referência ao elemento de entrada.
O hook useRef no React é comumente usado para:
- Gerenciar valores: Armazena valores mutáveis que não causam uma nova renderização quando atualizados.
- Acessar elementos do DOM: Permite acessar e modificar elementos do DOM de forma imperativa.
- Integrar com bibliotecas DOM de terceiros: Pode ser usado para integrar com bibliotecas DOM externas.
- Gerenciar foco, seleção de texto ou reprodução de mídia: Útil para manipular o foco, selecionar texto ou controlar a reprodução de mídia.
- Engatilhar animações imperativas: Pode ser usado para iniciar animações imperativas.
- Acessar as props ou o estado anterior de um componente funcional: Permite acessar as props ou o estado anterior de um componente funcional.
---
useImperativeHandle
useImperativeHandle personaliza a instância que é exposta aos pais quando usam ref.
import React, { useRef, useImperativeHandle } from 'react';
function FancyInput(props, ref) {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
}
}));
return <input ref={inputRef} ... />;
}
FancyInput = forwardRef(FancyInput);
Neste exemplo, useImperativeHandle é usado para expor a função focus para os pais.
O hook useImperativeHandle no React é comumente usado para:
- Expor instâncias de componentes filhos: Permite que um componente pai chame métodos ou acesse propriedades da instância do componente filho diretamente.
- Personalizar o valor de uma ref: Permite customizar o valor de uma ref do elemento pai através do componente filho.
- Expor métodos específicos: É utilizado para definir quais métodos e propriedades devem ser expostos para o componente pai através da referência.
- Interagir com componentes filhos: É particularmente útil quando precisamos interagir com um componente filho a partir de um componente pai.
---
useLayoutEffect
A assinatura de useLayoutEffect é idêntica à de useEffect, mas ele dispara efeitos síncronos após todas as mutações do DOM. Use isso para ler o layout do DOM e sincronizar a renderização.
import React, { useLayoutEffect, useState } from 'react';
function Example() {
const [width, setWidth] = useState(0);
useLayoutEffect(() => {
// Atualiza a largura da janela
function updateWidth() {
setWidth(window.innerWidth);
}
// Adiciona o evento de redimensionamento da janela
window.addEventListener('resize', updateWidth);
// Remove o evento de redimensionamento da janela
return () => window.removeEventListener('resize', updateWidth);
}, []); // Array vazio significa que este efeito não depende de nenhuma prop ou estado
return <div>A largura da janela é: {width}</div>;
}
Este exemplo usa useLayoutEffect
para adicionar um ouvinte de evento que atualiza a largura da janela quando a janela é redimensionada. A largura da janela é então exibida no componente.
O hook useLayoutEffect no React é comumente usado para:
- Atualizações síncronas do DOM: Executa antes do navegador atualizar a tela, garantindo que as alterações sejam aplicadas de forma síncrona.
- Medição de elementos do DOM: Útil para medir elementos do DOM antes da atualização do navegador.
- Animações e transições: Recomendado para animar ou fazer transições de elementos.
- Prevenir inconsistências visuais: Evita que o usuário receba uma inconsistência visual ao disparar mutações do DOM de forma síncrona antes da próxima atualização.
A “pintura de tela” é um termo usado para descrever o processo do navegador de desenhar elementos na tela após qualquer alteração no DOM. É nesse momento que o usuário vê as alterações aplicadas na interface do usuário.
---
useDebugValue
useDebugValue pode ser usado para exibir uma etiqueta para Hooks personalizados em React DevTools.
import React, { useState, useEffect, useDebugValue } from 'react';
function useFriendStatus(friendID) {
const [isOnline, setIsOnline] = useState(null);
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
useEffect(() => {
ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
};
});
// Exibe uma etiqueta no DevTools ao lado deste Hook
useDebugValue(isOnline ? 'Online' : 'Offline');
return isOnline;
}
Neste exemplo, ChatAPI é um módulo fictício que permite assinar o status online de um amigo. Quando o componente é montado, ele se inscreve no status online do amigo e, quando é desmontado, cancela a inscrição. O useDebugValue é usado para exibir o status online do amigo no DevTools.
O hook useDebugValue no React é comumente usado para:
- Depuração de Hooks Personalizados: Permite adicionar etiquetas aos hooks personalizados para facilitar a depuração.
- Exibição de Valores: Mostra valores úteis durante a depuração no inspetor de componentes do React DevTools.
- Formatar Valores Complexos: Pode ser usado com uma função de formatação para evitar cálculos pesados a menos que o hook esteja sendo inspecionado.
---
Conclusão
Esses são todos os Hooks disponíveis. Cada um tem seu próprio propósito e utilidade. Experimente-os e veja como eles podem melhorar seu código!
Lembre-se, os Hooks são completamente opcionais e 100% retrocompatíveis. Então, sinta-se à vontade para experimentá-los no seu próprio ritmo. Feliz codificação!
Tem alguma consideração a fazer? Deixe sua contribuição!!!
Você pode me encontrar em:
https://bento.me/magominimalista