DEV Community

Cover image for ⚛Os 10 React Hooks Mais Úteis: 05 - useReducer⚛
Marcelo Petry
Marcelo Petry

Posted on • Edited on

⚛Os 10 React Hooks Mais Úteis: 05 - useReducer⚛

Este é o quinto artigo de uma série de 10, que explica de forma simplificada e com exemplos, os react hooks mais utilizados em programação.


O useReducer é um hook do React que permite gerenciar o estado de um componente de forma semelhante ao reducer do Redux.

O useReducer é útil quando você precisa gerenciar um estado mais complexo ou compartilhado por vários componentes em sua aplicação. Ele também pode ser uma alternativa mais eficiente ao useState em casos em que o estado depende de valores anteriores, pois o useReducer só requer que você forneça o próximo estado, em vez de todo o estado atual.

O primeiro parâmetro do useReducer é o reducer, que é uma função que recebe o estado atual e uma ação como entrada e retorna o próximo estado. O reducer é responsável por atualizar o estado de acordo com a ação fornecida. Ele é geralmente escrito como um switch statement que verifica o tipo da ação e retorna o próximo estado de acordo com a ação correspondente.

O segundo parâmetro do useReducer é o estado inicial, que é o valor inicial do estado do componente. Ele é passado como o primeiro argumento para o reducer quando o componente é montado pela primeira vez. Ao chamar o useReducer, o hook retorna um par de valores: o estado atual e a função de dispatch. O estado atual é o valor atual do estado do componente, que é atualizado pelo reducer sempre que uma ação é despachada. A função de dispatch é usada para despachar uma ação para o reducer, o que atualiza o estado do componente.

Empregos do useReducer

Entenda o funcionamento do react hook useReducer com os exemplos abaixo.

1. Contador com useReducer

Acompanhe abaixo no arquivo Files>src>App.jsx o exemplo de um contador simples sobre o uso desse hook:

1 - import { useReducer } from "react": este comando importa o hook useReducer do módulo react.
2 - function reducer(state, action): esta é uma função chamada reducer, que recebe dois argumentos: state e action.
3 - switch (action.type): neste trecho, o valor do atributo type da ação é usado para escolher qual ação será realizada.
4 - case "increment": se o valor do atributo type da ação for "increment", será executado o código abaixo deste case.
5 - return { count: state.count + 1 }: este comando retorna um novo objeto com o valor de count incrementado em 1 em relação ao valor atual.
6 - case "decrement": se o valor do atributo type da ação for "decrement", será executado o código abaixo deste case.
7 - return { count: state.count - 1 }: este comando retorna um novo objeto com o valor de count decrementado em 1 em relação ao valor atual.
8 - default: se o valor do atributo type da ação não for reconhecido pelos cases acima, será executado o código abaixo deste default.
9 - throw new Error(): este comando lança uma exceção, interrompendo a execução do código.
10 - function Counter(): esta é uma função que retorna um componente do React.
11 - const [state, dispatch] = useReducer(reducer, { count: 0 }): este comando usa o hook useReducer para gerenciar o estado do componente. O primeiro argumento é o reducer definido anteriormente, e o segundo é o estado inicial, um objeto com o valor de count igual a 0. O useReducer retorna um array com dois elementos: o primeiro é o estado atual, e o segundo é uma função chamada dispatch, que permite disparar uma ação para o reducer.
12 - dispatch({ type: "increment" })}>+: este é um botão que, quando clicado, dispara uma ação de tipo "increment" para o reducer usando a função dispatch.
13 - dispatch({ type: "decrement" })}>-: este é um botão que, quando clicado, dispara uma ação de tipo "decrement" para o reducer usando a função dispatch.

2. Hook useReducer aplicado à lista de tarefas

No exemplo abaixo, o componente Files>src>App.jsx exibe uma lista de tarefas, um formulário para adicionar novas tarefas e botões para marcar tarefas como concluídas ou removê-las. Acompanhe:

1 - React e useReducer são importados do pacote react.
2 - initialState é uma constante que armazena um array vazio, que será o estado inicial do componente.
3 - reducer é uma função que recebe o estado atual e uma ação como argumentos e retorna um novo estado. Ela possui um switch case com três casos possíveis, correspondentes às ações "ADD_TASK", "TOGGLE_TASK" e "REMOVE_TASK".
4 - TaskList é uma função que retorna um componente React. Ela utiliza o hook useReducer para gerenciar o estado do componente, passando como primeiro argumento a função reducer e como segundo argumento o estado inicial, armazenado na constante initialState.
5 - handleSubmit é uma função que é chamada quando o formulário é submetido. Ela previne o comportamento padrão de recarregar a página e envia uma ação do tipo "ADD_TASK" com o texto digitado no campo de input como payload. Ela também limpa o campo de input.
6 - handleToggleTask é uma função que é chamada quando o checkbox de uma tarefa é clicado. Ela envia uma ação do tipo "TOGGLE_TASK" com o id da tarefa como payload.
7 - handleRemoveTask é uma função que é chamada quando o botão "Remove" de uma tarefa é clicado. Ela envia uma ação do tipo "REMOVE_TASK" com o id da tarefa como payload.
8 - O componente é retornado com um formulário para adicionar uma nova tarefa, uma lista de tarefas e, para cada tarefa, um checkbox para marcar como concluída e um botão para remover. Cada tarefa possui o texto da descrição e o id como chave única.
9 - O componente é exportado para que possa ser utilizado em outros arquivos.

3. Hook useReducer em Formulário de Nome/E-mail

Outro exemplo para compreendermos o useReducer é no caso em que precisamos manipular os dados de um formulário em nosso aplicativo. O reducer define o que acontece com o estado quando as ações são emitidas e usamos o gancho para controlar o estado inicial. Depois, temos campos de entrada que emitem ações para o nosso reducer e um botão de redefinição para redefinir os dados do formulário. Veja em Files>src>App.jsx:

1 - import React, { useReducer } from 'react';: Essa linha importa o React e o hook useReducer do pacote react.
2 - const initialState = { formData: { name: '', email: '' } };: Essa constante define o estado inicial do componente como um objeto que contém um objeto aninhado chamado formData, que, por sua vez, contém os campos de formulário name e email inicializados como strings vazias.
3 - function reducer(state, action) { ... }: Essa função é o reducer que será usado pelo hook useReducer. Ele recebe dois argumentos: o estado atual e uma ação. A função verifica o tipo de ação e, em seguida, retorna um novo estado de acordo.
4 - const [state, dispatch] = useReducer(reducer, initialState);: Essa linha usa o hook useReducer para gerenciar o estado do componente. Ela recebe dois argumentos: o reducer e o estado inicial. Em seguida, ela desestrutura o valor retornado pelo hook em duas variáveis: o estado atual e uma função chamada dispatch, que pode ser usada para enviar ações para o reducer.
5 - const handleUpdateFormData = formData => dispatch({ type: 'UPDATE_FORM_DATA', formData });: Essa função é um manipulador de eventos que é chamado quando os campos de formulário são alterados. Ele recebe um objeto formData como argumento e usa a função dispatch para enviar uma ação do tipo UPDATE_FORM_DATA para o reducer, passando o objeto formData como um segundo argumento.
6 - const handleResetFormData = () => dispatch({ type: 'RESET_FORM_DATA'});: Essa função é um manipulador de eventos que é chamado quando o botão "Reset" é clicado. Ele usa a função dispatch para enviar uma ação do tipo RESET_FORM_DATA para o reducer.
7 - <form>: Essa é a tag principal do formulário.
8 - <input type="text" name="name" value={state.formData.name} placeholder="Enter Your Name" onChange={e => handleUpdateFormData({[e.target.name]: e.target.value })} />: Essa é uma entrada de texto para o campo de nome. Ela recebe o valor atual do campo de nome doestado através da propriedade value, e usa o manipulador de eventos handleUpdateFormData para atualizar o estado quando o campo é alterado.
9 - handleUpdateFormData({ [e.target.name]: e.target.value })} />: este é um elemento de entrada HTML que representa um campo de formulário para o usuário inserir o endereço de e-mail. Quando o usuário digita um valor no campo, a função handleUpdateFormData é chamada para atualizar os dados do formulário.
10 - Reset: este é um elemento de botão HTML que tem um evento onClick que chama a função handleResetFormData quando o botão é clicado. Isso faz com que os dados do formulário sejam redefinidos para seus valores iniciais.
11 - export default App;: este código exporta o componente App para que ele possa ser usado em outros arquivos.

4. Formulário de busca com useReducer

Neste exemplo, testaremos o hook useReducer em um componente de formulário de busca. Acompanhe pelo Files>src>App.jsx:

1 - import React, { useReducer } from 'react';: Importa o módulo react e a função useReducer do módulo react.
2 - import './App.css': Importa o arquivo de estilos App.css para o componente App.
3 - const initialState = { query: '', results: [] };: Define o estado inicial do componente App, contendo um objeto com as propriedades query e results. A propriedade query armazena a string de pesquisa atual, enquanto a propriedade results armazena os resultados da pesquisa.
4 - const reducer = (state, action) => {...}: Define uma função reducer que recebe um estado atual e uma ação e retorna um novo estado. A função reducer é usada pelo useReducer para atualizar o estado do componente.
5 - const App = () => {...}: Define o componente App como uma função.
6 - const [state, dispatch] = useReducer(reducer, initialState);: Chama a função useReducer passando a função reducer e o estado inicial como argumentos. A função useReducer retorna um array com o estado atual e uma função dispatch que pode ser usada para disparar ações para a função reducer. O estado atual é armazenado na variável state, enquanto a função dispatch é armazenada na variável dispatch.
7 - const handleInputChange = e => {...};: Define uma função handleInputChange que é chamada toda vez que o usuário altera o valor do input de pesquisa. A função dispara uma ação UPDATE_QUERY para a função reducer, passando o valor atual do input como argumento.
8 - const handleSearch = () => {...};: Define uma função handleSearch que é chamada toda vez que o usuário clica no botão "Search". A função simula uma chamada a uma API, gerando alguns resultados de pesquisa fictícios e disparando uma ação UPDATE_RESULTS para a função reducer, passando os resultados como argumento.
9 - const handleReset = () => {...};: Define uma função handleReset que é chamada toda vez que o usuário clica no botão "Reset". A função dispara uma ação RESET para a função reducer, reinicializando o estado do componente para o estado inicial.
10 - return (...): Retorna o elemento JSX que representa o componente App. O elemento inclui um input de texto que exibe o valor da propriedade query do estado atual e chama a função handleInputChange toda vez que o valor é alterado. Também inclui dois botões que chamam as funções handleSearch e handleReset quando clicados. Por fim, o elemento inclui um conjunto de elementos div que exibem os resultados da pesquisa armazenados na propriedade results do estado atual.


Conclusão

O useReducer é um hook do React que permite que um componente gerencie seu próprio estado de maneira semelhante ao padrão reducer de uma aplicação Redux.

Ao invés de armazenar o estado diretamente no componente, o estado é armazenado em uma função reducer, que toma o estado atual e uma ação como argumentos e retorna o próximo estado da aplicação. Isso permite que a lógica de atualização do estado seja centralizada e facilita o gerenciamento de mudanças de estado complexas em componentes.

Além disso, o uso do useReducer pode tornar o código mais legível, pois a lógica de atualização do estado é isolada em uma única função, em vez de espalhada por todo o componente.

No entanto, é importante lembrar de que o useReducer não é a solução ideal para todos os casos e deve ser usado com moderação, considerando as necessidades específicas da sua aplicação.


marcelopetry.com

Top comments (0)