React Hooks: como usar e por que são úteis
Tags: javascript, react, reacthooks, development
Published: 2023-05-02 13:04:22

O React é uma biblioteca JavaScript popular para construir interfaces de usuário interativas e reativas. Com o lançamento dos React Hooks, em 2019, tornou-se ainda mais fácil e eficiente criar componentes reutilizáveis e stateful.

Os Hooks são uma nova adição ao React 16.8 que permite que os desenvolvedores usem o state e outros recursos do React sem escrever classes. 

Os Hooks são funções que permitem que você use o state e outros recursos do React em componentes de função. Isso significa que agora você pode ter state e métodos de ciclo de vida em componentes de função, em vez de apenas em componentes de classe.

Existem alguns Hooks diferentes no React, cada um com seu próprio propósito. Neste artigo, veremos e entendenderemos  como usar os Hooks mais comuns e os benefícios que eles oferecem.

## useState

O Hook useState permite que você adicione state a componentes de função. Com o useState, você pode criar variáveis ​​de estado que atualizam automaticamente sempre que você altera o valor.

Exemplo:

```tsx
import React, { useState } from 'react';

function App() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
```

No exemplo acima, podemos ver que a cada clique no botão será adicionado +1 na contagem e será atualizado em tela o novo valor dessa contagem.

## useEffect

O Hook useEffect permite que você execute efeitos secundários em componentes de função. Efeitos secundários são ações que ocorrem fora do escopo normal da renderização, como a busca de dados de uma API ou a adição de eventos ao DOM.

```tsx
import React, { useState, useEffect } from 'react';

function App() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

```

No exemplo acima, podemos ver que a cada clique no botão será adicionado +1 na contagem e cada vez que essa contagem for atualizada o titulo da página será modificado com a nova contagem.

## useContext

O hook useContext é um recurso muito útil do React para compartilhar dados entre componentes sem precisar passá-los através de várias camadas de props. 

Basicamente, ele permite que você acesse um objeto de contexto que contém dados compartilhados em qualquer nível da sua árvore de componentes.

Para utilizar o hook useContext, você precisa primeiro criar um objeto de contexto com a função createContext().

Exemplo:

```tsx
import { createContext } from 'react';

const MeuContexto = createContext();

```

Em seguida, você pode usar o provider do contexto para fornecer os dados compartilhados para os componentes abaixo na hierarquia. 

Exemplo:


```tsx
import { useState } from 'react';
import { MeuContexto } from './MeuContexto';

function App() {
  const [dados, setDados] = useState({});

  return (
    <MeuContexto.Provider value={{ dados, setDados }}>
      <MeuComponente />
    </MeuContexto.Provider>
  );
}

```

No exemplo acima, estamos fornecendo um objeto contendo dados e uma função de atualização para o MeuContexto.Provider. 

Agora, qualquer componente abaixo na árvore de componentes pode acessar esses dados usando o hook useContext. 

Exemplo:

```tsx
import { useContext } from 'react';
import { MeuContexto } from './MeuContexto';

function MeuComponente() {
  const { dados, setDados } = useContext(MeuContexto);

  function handleClick() {
    setDados({ mensagem: 'Olá, mundo!' });
  }

  return (
    <div>
      <p>{dados.mensagem}</p>
      <button onClick={handleClick}>Atualizar dados</button>
    </div>
  );
}

```

No exemplo acima, estamos usando o hook useContext para acessar o objeto de contexto MeuContexto e obter os dados e a função de atualização. 

Em seguida, exibimos a mensagem na tela e definimos um manipulador de eventos para atualizar os dados quando o botão for clicado.

## useReducer

O Hook useReducer é uma alternativa ao useState que é útil quando o estado é um objeto ou uma matriz complexa. 

O useReducer é um hook do React que permite gerenciar o estado de um componente usando uma abordagem baseada em ações. 

Ele é especialmente útil quando se lida com estados complexos e com múltiplos valores que precisam ser atualizados em conjunto.

O hook useReducer funciona de forma semelhante a uma implementação do padrão de projeto "Reducer" em JavaScript. Ele recebe dois argumentos: uma função "reducer" e um estado inicial.

Exemplo: 

```tsx
import { 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 (
    <>
      <div>Count: {state.count}</div>
      <button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
    </>
  );
}

```

Neste exemplo, o estado inicial é um objeto com a propriedade count igual a 0. A função reducer verifica o tipo da ação e atualiza o estado de acordo com o valor atual do count.

O componente Counter usa o useReducer para gerenciar o estado do contador. Ele usa o dispatch para enviar a ação para a função reducer e atualizar o estado.

## useCallback

O useCallback é um hook do React que permite memorizar funções para que elas não sejam recriadas em cada renderização de um componente. 

Isso pode ser útil para evitar a criação desnecessária de novas funções, especialmente quando se lida com componentes com muitas atualizações de estado.

O useCallback recebe duas dependências: uma função e uma lista de dependências. 

A função é a que será memorizada e a lista de dependências é opcional e serve para que o useCallback só recrie a função quando houver uma alteração nas dependências.

Exemplo: 

```tsx
import { useState, useCallback } from 'react';

function Button(props) {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    setCount(count + 1);
  }, [count]);

  return (
    <button onClick={handleClick}>
      Click me ({count})
    </button>
  );
}

```

Neste exemplo, o componente Button tem um estado count que é atualizado quando o botão é clicado. A função handleClick é a função que será executada quando o botão for clicado e usa o setCount para atualizar o estado.

Usando o useCallback com a dependência count, a função handleClick só será recriada quando o count for alterado, evitando assim que seja criada uma nova função a cada renderização do componente.

### Dicas bônus

#### useEffect

Quando não se aplica o segundo paramêtro(exemplo: []) do hook useEffect, esse hook funciona como a função componentDidUpdate de um componente de classe.

Ou seja  sem o segundo parâmetro, os efeitos são executados após cada renderização, e definindo um novo estado acionará os efeitos novamente.

Exemplo:

```tsx
import React, { useState, useEffect } from 'react';

function App() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

```

Quando se aplica o segundo parâmetro e se colocar apenas parênteses vazios o useEffect, esse hook funciona como a função componentDidMount de um componente de classe.

Ou seja  com o segundo parâmetro, os efeitos são executados apenas após o componente ser criado/montado.

Exemplo:

```tsx
import React, { useState, useEffect } from 'react';

function App() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  },[]);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

```

Quando se aplica um return no useEffect, esse return funciona como a função componentWillUnmount de um componente de classe.

Ou seja a função/rotina quer for colocada no return , será executado assim que o componente for desmontado ou removido do DOM.

Exemplo:

```tsx
import React, { useState, useEffect } from 'react';

function App() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
    return console.log('componente destruido');
  },[]);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

```

#### useCallback

O useCallback é particularmente útil quando usado em conjunto com outros hooks, como o useEffect. 

Em vez de passar uma função anônima diretamente para o useEffect, pode-se usar o useCallback para memorizar a função e passá-la como uma dependência para o useEffect.

Exemplo: 

```tsx
import { useState, useCallback, useEffect } from 'react';

function Component(props) {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    setCount(count + 1);
  }, [count]);

  useEffect(() => {
    console.log('Componente montado.');
    return () => {
      console.log('Componente desmontado.');
    };
  }, [handleClick]);

  return (
    <button onClick={handleClick}>
      Click me ({count})
    </button>
  );
}

```

Neste exemplo, a função handleClick é memorizada com o useCallback e passada como dependência para o useEffect. Isso garante que o useEffect só seja reexecutado quando a função handleClick for recriada.

Em resumo os Hooks são funções que permitem que você use o state e outros recursos do React em componentes de função.
Além dos hooks acima existem muitos outros [hooks](https://legacy.reactjs.org/docs/hooks-reference.html#gatsby-focus-wrapper) que você pode explorar.

Espero que tenha gostado.

Referencias:

[React hooks docs](https://legacy.reactjs.org/docs/hooks-reference.html#gatsby-focus-wrapper)

[React References](https://react.dev/reference/react)

[Ciclos de Vida React](https://retool.com/blog/the-react-lifecycle-methods-and-hooks-explained/#:~:text=A%20React%20component%20undergoes%20three%20phases%20in%20its%20lifecycle%3A%20mounting,often%20called%20%E2%80%9Cinitial%20render.%E2%80%9D)

[useEffect](https://overreacted.io/pt-br/a-complete-guide-to-useeffect/)