Se você usou o React para construir um aplicativo da web, é provável que você tenha enfrentado grandes desafios com o gerenciamento de estado. Por muito tempo, contamos com Redux para gerenciamento de estado, mas por causa de sua complexidade e quantidade excessiva de código, eventualmente nos voltamos para outras soluções como RxJS/React Hooks e a API React Context. Também vimos o Redux Toolkit resolver o problema do boilerplate do Redux-e posso argumentar que é a mais simples de todas as ferramentas que acabei de mencionar.
Em seguida, há o useState
Hook do React para gerenciamento de estado local. Se você já trabalhou com isso antes, pode ter se perguntado por que o gerenciamento de estado global não pode ser tão fácil. Por que ainda precisamos de tanto texto padronizado para gerenciar o estado com a API de contexto? E se não quisermos ser limitados por ferramentas opinativas como o Redux Toolkit ou forçados a usar ações e redutores em nossos aplicativos React?
É aqui que entra o Hookstate. Hookstate não é apenas mais uma solução de gerenciamento de estado. Além de ser rica em recursos, rápida e flexível, a biblioteca leva a ideia de simplificar o gerenciamento de estado em aplicativos React a um nível totalmente novo.
Hookstate funciona quase exatamente como o gancho React useState
. Na verdade, com o Hookstate, criar um estado global é tão fácil quanto criar um estado local com o gancho useState
. Além de sua simplicidade, o Hookstate também estende nossa instância de estado criada com outros recursos úteis.
Neste artigo, apresentaremos o Hookstate como uma solução de gerenciamento de estado simples e eficiente para aplicativos React, criando um aplicativo de bate-papo de demonstração. O único pré-requisito necessário para acompanhar este artigo é o conhecimento do React.
Hookstate e seus recursos
Como o próprio nome sugere, Hookstate é uma ferramenta de gerenciamento de estado rápida e flexível baseada em o gancho do estado React. É uma pequena biblioteca repleta de recursos que incluem estados globais e locais, bem como atualizações de estado parciais e estados carregados de forma assíncrona.
Nosso foco para este artigo está no pacote @ hookstate/core
, mas Hookstate tem vários plug-ins opcionais que nos permitem estender ou personalizar nossos ganchos de estado-e a documentação da biblioteca é bem escrita e repleta de boas demonstrações. Abaixo estão alguns plug-ins dignos de nota:
-
@ hookstate/persistence
nos permite manter nosso estado no armazenamento local do navegador, o que é útil para aplicativos offline ou se você quiser que um usuário retenha seus dados de estado após recarregar a página -
@ hookstate/validation
pode ser muito útil para campos de formulário porque permite a validação e mensagens de erro/aviso para um estado -
@ hookstate/broadcasted
é uma ferramenta muito útil se você deseja habilitar a sincronização do seu estado em diferentes guias do navegador
Vamos explorar alguns dos principais recursos do Hookstate que o tornam uma boa escolha para gerenciamento de estado em aplicativos React. Faremos isso criando um aplicativo de bate-papo. Esta é a aparência de nosso aplicativo ao final do artigo:
Nosso aplicativo de bate-papo terá dois componentes que serão capazes de interagir um com o outro, enviando e recebendo dados de nossa loja Hookstate global.
Construindo nosso aplicativo com React e Hookstate
Vamos começar usando o pacote create-react-app
para gerar um novo aplicativo React. Vamos executar o seguinte comando em nosso terminal:
npx create-react-app hookstate-chat
A seguir, vamos cd
em nosso novo diretório hookstate-chat
e instalar o Hookstate:
cd hookstate-chat npm install--save @ hookstate/core
Configurando os componentes da nossa caixa de bate-papo
Agora que instalamos o Hookstate, vamos instalar o react-custom-chat
. Eu criei este pacote npm para este artigo para que possamos nos concentrar em Hookstate e não ter que nos preocupar com o design de nosso aplicativo de bate-papo, mas você pode usar ou construir outro, se quiser:
npm install--save react-custom-chat
Com o react-custom-chat
instalado, vamos ao diretório ./src
e criar um arquivo JSX para nosso primeiro componente de chat. Vamos chamá-lo de FirstPerson
.
A seguir, adicionaremos o seguinte código ao nosso arquivo ./src/FirstPerson.jsx
:
importar ChatBox de'react-custom-chat' const FirstPerson=()=> { Retorna ({}}//faça algo com newMessage configurações={{ posição:'esquerda', navColor:'green', navText:'Mycroft' }} /> ) } exportar FirstPerson padrão
Em nosso componente FirstPerson
, começamos importando ChatBox
do pacote react-custom-chat
. O componente ChatBox
tem um prop messageList
, que conterá uma matriz de nossos objetos de mensagem. Cada objeto de mensagem conterá:
- Uma propriedade
text
do tipostring
, que representa o texto da mensagem - Uma propriedade
person
do tipostring
, que pode ser “primária” ou “secundária”
A propriedade person
ajuda o componente ChatBox
a determinar como definir o estilo de cada mensagem.
O prop onSendMessage
espera uma função que dirá o que fazer sempre que uma mensagem for enviada.
Por último, adicionamos uma propriedade settings
para definir a aparência de nossas caixas de bate-papo. Nesse caso, queremos que a caixa de bate-papo do FirstPerson seja posicionada à esquerda de nossa página.
Vamos fazer o mesmo com nossa caixa de bate-papo SecondPerson. Vamos criar um arquivo JSX chamado SecondPerson
em nosso diretório ./src
e colar o seguinte código nele:
importar ChatBox de'react-custom-chat' const SecondPerson=()=> { Retorna ({}} configurações={{ Posição à direita', navColor:'blue', navText:'Cortana' }} /> ) } exportar SecondPerson padrão
Observe como alteramos a posição, a cor de navegação e o texto de nossa caixa de bate-papo do SecondPerson. Você pode encontrar outras configurações personalizadas para o componente ChatBox
em documentação do react-custom-chat
.
Colocando nossos componentes de chat em uso
Com nossos componentes de chat criados com sucesso, agora podemos importá-los e usá-los em nosso arquivo ./src/App.js
. Vamos substituir o que está lá atualmente pelo seguinte código:
importar FirstPerson de'./FirstPerson' importar SecondPerson de'./SecondPerson' const App=()=> { Retorna ( <>> ); } exportar aplicativo padrão
Podemos prosseguir e iniciar nosso aplicativo executando npm start
em nosso terminal. Devemos ver uma página semelhante a esta quando abrirmos nosso aplicativo no navegador:
Clicar nos ícones de bate-papo deve abrir nossas janelas de bate-papo:
Criando nossa loja global com Hookstate
Agora que criamos com sucesso nossos componentes de bate-papo, vamos usar o Hookstate para configurar e gerenciar a funcionalidade de mensagem de nosso aplicativo. Começaremos criando um novo arquivo JavaScript denominado store.js
no diretório ./src
, que abrigará o estado global de nosso aplicativo.
Hookstate não tem nenhuma restrição sobre onde você pode criar estados globais, contanto que qualquer componente que precise dele seja capaz de importá-lo com sucesso.
Dentro de nosso arquivo ./src/store.js
, usaremos o método createState
do Hookstate para criar nosso estado:
import {createState} de'@ hookstate/core' const store=createState ({ firstPersonMessageList: [], secondPersonMessageList: [] }) exportar loja padrão
Como alternativa, podemos criar nossos estados FirstPerson
e SecondPerson
individualmente:
...
const firstPersonMessageList=createState ([])
const secondPersonMessageList=createState ([])
...
Qualquer uma das opções funcionará bem para nosso aplicativo porque Hookstate nos permite criar quantos estados quisermos e também nos fornece a capacidade de atualizar facilmente propriedades de estados aninhados. Para o propósito de nosso tutorial, vamos usar a primeira abordagem.
Também fornecemos o método createState
com um estado de objeto inicial que contém as propriedades firstPersonMessageList
e secondPersonMessageList
.
Com nosso estado criado com sucesso, podemos ir em frente e acessá-lo com o gancho useState
do Hookstate. Como é um gancho do React, precisaremos chamá-lo dentro de nossos componentes do React. Nosso estado retornado do gancho useState
terá:
- Um método
get ()
que podemos usar para obter os dados de estado - Um método
set ()
para definir um novo valor para nosso estado - Um método
merge ()
para adicionar dados ao nosso estado
Existem também outros métodos como attach ()
e batch ()
, mas não precisaremos deles para nosso aplicativo de demonstração.
Acessando e atualizando nossa loja global
Vamos ver como podemos acessar e atualizar nossa loja a partir de componentes individuais. Iremos para o arquivo ./src/FirstPerson.jsx
e importar o gancho useState
do Hookstate. Também importaremos nossa loja do arquivo store.js
:
import {useState} de'@ hookstate/core' importar loja de'./store' ...
Agora podemos usar o gancho useState
para acessar nossa loja. Como useState
é um gancho React, precisaremos usá-lo dentro do corpo de nosso componente FirstPerson
. Vamos criar uma variável chamada globalState
e chamar o gancho useState
com nosso armazenamento importado como seu valor.
... const FirstPerson=()=> { const globalState=useState (armazenar) ... } exportar FirstPerson padrão
A variável globalState
deve conter o estado inicial que fornecemos à nossa loja. Também podemos desestruturar diretamente as propriedades firstPersonMessageList
e secondPersonMessageList
ao usar o gancho useState
para acessar nossa loja. Vamos mudar nossa declaração de variável globalState
para a seguinte linha de código:
const {firstPersonMessageList, secondPersonMessageList}=useState (armazenar)
Agora, podemos usar firstPersonMessageList
e secondPersonMessageList
como estados individuais.
Esta é uma vantagem poderosa do Hookstate porque nossas propriedades aninhadas também têm os métodos de estado que nossa variável globalState
teria. Agora podemos usar igualmente os métodos get ()
, set ()
e merge ()
em nossas propriedades desestruturadas.
Tratamento do evento sendMessage
do usuário
A seguir, vamos criar nossa função para lidar com o evento do usuário sendMessage
. Vamos chamá-lo de handleSendMessage
:
... const handleSendMessage=newMessage=> { firstPersonMessageList.merge ([{text: newMessage, person:'principal'}]) secondPersonMessageList.merge ([{text: newMessage, person:'secondary'}]) }
No bloco acima, criamos uma função chamada handleSendMessage
e fornecemos a ela um parâmetro chamado newMessage
. Nosso parâmetro newMessage
representa tudo o que nosso usuário digita no campo de entrada do chat. Para cada nova mensagem primária que adicionamos ao firstPersonMessageList
, também estamos fazendo uma adição secundária correspondente ao secondPersonMessageList
. Faremos o inverso quando chegarmos ao componente SecondPerson.
Observe como é fácil atualizar nosso estado com o método merge ()
. Se estivéssemos usando o método set ()
ou o gancho useState
interno do React, nossa função seria semelhante a esta:
const handleSendMessage=newMessage=> { firstPersonMessageList.set ([... firstPersonMessageList, {text: newMessage, person:'principal'}]) secondPersonMessageList.merge ([... secondPersonMessageList, {text: newMessage, person:'secondary'}]) }
Nossa segunda função definitivamente parece mais complexa do que a primeira. Com o método merge ()
, se o valor do estado atual e o argumento forem ambos arrays, o Hookstate fará o trabalho de concatenar o valor atual com o valor do argumento e configurá-lo para o estado. Você pode ver outras maneiras de usar o método merge ()
no documentação do Hookstate .
Apenas para fins estéticos, vamos atrasar a atualização do estado secondPersonMessageList
em 500 milissegundos:
... const handleSendMessage=newMessage=> { firstPersonMessageList.merge ([{text: newMessage, person:'principal'}]) setTimeout (()=> { secondPersonMessageList.merge ([{text: newMessage, person:'secondary'}]) }, 500) } ...
Agora podemos fornecer a função handleSendMessage
como nosso valor prop ChatBox
onSendMessage
. Também usaremos o método get ()
de nosso firstPersonMessageList
para acessar nosso estado e, em seguida, usá-lo como o valor para nosso ChatBox
messageList
prop:
......
Nosso arquivo FirstPerson.jsx
agora deve ter a seguinte aparência:
import {useState} de'@ hookstate/core' importar ChatBox de'react-custom-chat' importar loja de'./store' const FirstPerson=()=> { const {firstPersonMessageList, secondPersonMessageList}=useState (armazenar) const handleSendMessage=newMessage=> { firstPersonMessageList.merge ([{text: newMessage, person:'principal'}]) setTimeout (()=> { secondPersonMessageList.merge ([{text: newMessage, person:'secondary'}]) }, 500) } Retorna () } exportar FirstPerson padrão
Vamos fazer a mesma coisa em nosso arquivo SecondPerson.jsx
. Como já explicamos as etapas em detalhes, podemos prosseguir e colar o seguinte código em nosso arquivo:
import {useState} de'@ hookstate/core' importar ChatBox de'react-custom-chat' importar loja de'./store' const SecondPerson=()=> { const {firstPersonMessageList, secondPersonMessageList}=useState (armazenar) const handleSendMessage=newMessage=> { secondPersonMessageList.merge ([{text: newMessage, person:'principal'}]) setTimeout (()=> { firstPersonMessageList.merge ([{text: newMessage, person:'secondary'}]) }, 500) } Retorna () } exportar SecondPerson padrão
Na função handleMessage
para nosso componente SecondPerson
, fizemos o inverso do que fizemos no componente FirstPerson
: sempre que um a mensagem é enviada, ela é adicionada como primária à secondPersonMessageList
e como secundária à firstPersonMessageList
.
Agora, quando abrimos nosso aplicativo no navegador, devemos ser capazes de enviar mensagens através de nossos dois componentes por meio da ferramenta Hookstate:
Conclusão
Aprendemos como usar o Hookstate para gerenciamento de estado em aplicativos React. Também vimos por que o Hookstate não é apenas mais uma solução de gerenciamento de estado, mas uma ferramenta que leva a ideia de simplificar o gerenciamento de estado em aplicativos React a um nível totalmente novo.
Eu ainda não usei em um aplicativo de grande escala, mas até agora, ele provou ser uma biblioteca eficiente. Aqui estão links para a base de código para nosso react-custom-chat
package e nosso aplicativo de demonstração . Se você quiser manter contato, considere se inscrever em meu canal do YouTube e me seguir no GitHub. Continue construindo!
Leituras adicionais
- RxJS com React Hooks para o estado gestão
- Guia de referência do React: API de contexto
- Smarter Redux com Redux Toolkit
A postagem Simplifique o gerenciamento de estado do React com Hookstate apareceu primeiro no LogRocket Blog .