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:

Demonstração final do aplicativo de chat

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 tipo string , que representa o texto da mensagem
  • Uma propriedade person do tipo string , 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:

Página de inicialização do aplicativo de bate-papo

Clicar nos ícones de bate-papo deve abrir nossas janelas de bate-papo:

Aplicativo de bate-papo com janelas de bate-papo abertas

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:

Demonstração final do aplicativo de chat

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

A postagem Simplifique o gerenciamento de estado do React com Hookstate apareceu primeiro no LogRocket Blog .