Usando o Mobx como um gerenciador de estado em aplicativos React Native

Publicados: 2022-03-10
Resumo rápido ↬ MobX é uma das muitas ferramentas de gerenciamento de estado disponíveis para desenvolvedores React. Neste tutorial, Fortune Kay explica o que é o MobX e como você pode usá-lo em seus aplicativos React construindo um do zero.

O gerenciamento de estado é parte integrante do desenvolvimento de aplicativos JavaScript, especialmente aplicativos React e React Native. Neste tutorial, vamos aprender como usar a biblioteca MobX para gerenciamento de estado; entender os conceitos básicos, alguns casos de uso e construir um exemplo simples.

Nota: O conhecimento básico de Javascript e React Native será de grande benefício enquanto você trabalha neste tutorial.

Usando aplicativos MobX In React

Estado são os dados com os quais seu(s) componente(s) está(ão) trabalhando — ele contém os dados que um componente requer e determina o que um componente renderiza. Gerenciamento de estado é o processo de gerenciar como o estado é atualizado e passado de um componente para outro. Monitorar e trabalhar com dados em um aplicativo pode ser difícil e essa é a necessidade de bibliotecas de gerenciamento de estado. Manipular todos os dados para seu aplicativo pode ser um pouco assustador, especialmente quando seu aplicativo cresce em tamanho e complexidade, construir sua própria ferramenta de gerenciamento de estado não é apenas demorado, mas difícil. É por isso que você pode querer usar uma biblioteca de gerenciamento de estado.

No entanto, é importante saber que o estado não é o único dado que um componente renderiza, os componentes também podem renderizar props passados ​​para ele.

Opções para gerenciamento de estado

As bibliotecas de gerenciamento de estado para aplicativos React Native incluem; React Context API, Redux, MobX e Unstated Next.

Embora esses gerenciadores de estado tenham suas vantagens e desvantagens, eu pessoalmente recomendo o MobX por causa de sua simplicidade, código clichê mínimo — ele não exige que você altere seu código, porque em sua essência, o MobX é e se parece com JavaScript; você não precisa de uma mudança de arquitetura para suportá-lo (ao contrário do Redux e, em menor grau, do Contexto).

Na verdade, é uma abstração tão invisível que, em muitos casos, se você retirar todo o código MobX — os decoradores @observable , @computed , @action e Observer , seu código funcionará exatamente da mesma forma (embora tenha alguns problemas de desempenho ) e não se limita a um estado global. Estas são algumas razões para seguir em frente com o MobX como um gerenciador de estado de escolha para seus aplicativos React Native.

Embora também seja importante observar alguns problemas com o uso do MobX como gerenciador de estado, alguns dos quais incluem evitar regras sobre como implementá-lo e o MobX pode ser difícil de depurar, especialmente quando você altera o estado diretamente em um componente sem usar o @actions parâmetro.

O que é MobX?

De acordo com a documentação oficial, o MobX é uma biblioteca testada em batalha que torna o gerenciamento de estado simples e escalável, aplicando de forma transparente a programação reativa funcional. MobX trata seu aplicativo como uma planilha. A lógica é que qualquer coisa que possa ser derivada do estado do aplicativo deve ser feita automaticamente .

Arquitetura de estado MobX
Arquitetura de estado MobX. (Visualização grande)
Mais depois do salto! Continue lendo abaixo ↓

Princípios Fundamentais e Conceito do MobX

O MobX se diferencia dos demais gestores estaduais com os seguintes conceitos.

1. Estado

Estado são os dados que seu aplicativo contém — é aproximadamente todo o conteúdo de sua memória. Isso também se aplica aos seus componentes.

2. Derivações

No MobX, qualquer coisa que possa ser derivada do estado sem interações é uma derivação. Exemplos de derivações incluem:

  • Interface de usuário,
  • Complementos de back-end, como alterações em um servidor.

MobX tem dois tipos principais de derivações:

  • Valores calculados
    Valores calculados são principalmente valores que podem ser derivados de um estado atual usando funções puras.
  • Reações
    As reações nas derivações são efeitos colaterais que ocorrem como resultado de alterações no estado do aplicativo. Eles são semelhantes a um valor calculado, mas em vez de produzir um novo valor, uma reação produz um efeito colateral para coisas como imprimir no console, fazer solicitações de rede, atualizar incrementalmente a árvore de componentes React para corrigir o DOM e assim por diante.

Uma regra de ouro ao usar o MobX é que ao criar um valor baseado no estado atual, use um valor calculado.

3. Ações

Ao contrário das derivações, as ações são códigos que causam alterações no estado de um aplicativo — código que altera o estado. Eles são qualquer coisa que modifique o estado. Com o MobX você pode torná-lo explícito em seu código, ações são principalmente eventos de usuário, como entradas, push de dados de backend ou até mesmo eventos agendados.

Para entender melhor as ações, vejamos um exemplo da documentação do MobX.

 class Ticker { @observable tick = 0 @action increment() { this.tick++ // 'this' will always be correct } } const ticker = new Ticker() setInterval(ticker.increment, 1000)

Aqui, definimos um tick @observable com um valor inicial de 0. Em seguida, criamos um incremento de função que também é uma ação que atualiza o valor inicial uma vez que um tick é feito a cada segundo.

Observáveis ​​no MobX

Observáveis ​​ou valores observáveis ​​no MobX são principalmente primitivos JavaScript, objetos simples, classes, arrays e mapas. Eles são usados ​​principalmente declarando primeiro um observável e adicionando um valor a ele e, em seguida, chamando-o adicionando um @observable conforme mostrado abaixo:

 observable(value) @observable classProperty = value

Abordagem de arquitetura de loja no MobX

A arquitetura principal do MobX inclui partes e ideias como serviços, loja, modelos de visualização e contêineres — alguns dos quais são explicados abaixo.

  • Serviço
    Geralmente, é uma função chamada de um contêiner; eles podem ser usados ​​para obter dados de APIs e serem adicionados à loja.
  • Armazenar
    Como o nome indica, este é o local central do estado usado por um aplicativo. Normalmente no MobX, eles incluem os observáveis, variáveis, ações e propriedades computadas.
  • Recipiente
    Isso chama service e coloca os dados do View Model para o View Component como props React (deve ser marcado com o decorador @observer ).

MobX em React e Aplicativos Nativos

Para fins de aprendizado, neste tutorial, criaremos um aplicativo de lista simples que permitirá que um usuário adicione, visualize e exclua itens de lista. Usaremos o MobX como gerenciador de estado neste aplicativo para adicionar listas, atualizá-las e excluí-las do estado do aplicativo. No entanto, é importante notar que você já entende os conceitos básicos de JavaScript e React.

Sem mais delongas, vamos começar!

Configurando seu ambiente

Agora que sabemos o que é o MobX e como ele funciona, deixe-me orientá-lo na configuração do seu projeto.

Primeiro, vamos criar um projeto com o seguinte, escreva o seguinte código em seu terminal para inicializar um projeto:

 npx create-react-app listapp

O código acima criará um aplicativo React simples usando o pacote create-react-app. Mova para o diretório do projeto:

 cd listapp

Para este aplicativo, precisaremos de três componentes:

  • TitleInput
    Isso conterá o título do nosso projeto e um formulário de entrada para adicionar listas.
  • List
    Este será um formulário de entrada que permitiria a um usuário adicionar uma lista. Ele terá um botão adicionar para adicionar nossos itens de lista.
  • ListsDisplay
    Este componente exibirá todos os itens da lista de usuários e também um botão de exclusão que é gerado automaticamente quando um usuário adiciona um item de lista.

Usaremos um Store.js para conter o estado do aplicativo e métodos para modificá-lo de maneira semelhante ao Redux. Vamos descrever para que eles serão usados.

  • mobx
    Este é o gerenciador de estado que usaremos para este projeto.
  • mobx-react
    Esta é a ligação oficial do React para o MobX.
  • bootstrap
    Usaremos o bootstrap versão 4.5 para estilizar nosso projeto.
  • uuid
    Isso é usado para criar automaticamente chaves para excluir listas.

Feito isso, vamos instalar esses pacotes. Vou instalá-los com uma alternativa npm feita no fio:

 yarn add mobx mobx-react [email protected] uuid

Assim que os pacotes estiverem instalados, iniciaremos nosso aplicativo em modo de desenvolvimento executando o código abaixo em nosso terminal:

 yarn start

Configurando nossa App Store

Vamos criar uma loja para o nosso projeto. Primeiro, crie um arquivo no diretório raiz do nosso projeto chamado ListStore , este será o local central do estado do nosso aplicativo.

Para este aplicativo, precisaremos criar um ListStore para não nos repetirmos quando o usarmos em outros componentes do aplicativo.

 /*** src/Store.js ***/ import { observable, action, computed } from "mobx"; import { v4 } from "uuid"; export class List { @observable value @observable done constructor (value) { this.id = v4() this.value = value } } export class ListStore { @observable lists = [] @observable filter = "" @action addList = (value) => { this.lists.push(new List(value)) } @action deleteList = (list) => { this.lists = this.lists.filter(t => t !== list) } @computed get filteredLists () { const matchCase = new RegExp(this.filter, "i") return this.lists.filter(list=> !this.filter || matchCase.test(list.value)) } }

No código acima, importamos três funções do mobx .

  • observable
    Este contém uma variável que pode ser atualizada no caso de uma mudança de estado.
  • action
    Usado para modificar o estado do aplicativo.
  • computed
    Valores que podem ser derivados do estado existente ou de outros valores calculados, são alterados depois que um estado é modificado.

A classe List possui dois valores de objeto que são done e um value que manterá o estado inicial do aplicativo e a modificação no caso de alterações.

Queremos que nossa nova lista crie automaticamente uma chave para que possamos obter automaticamente um botão de exclusão assim que uma lista for criada. Aqui, uuid é usado para criar chaves automaticamente em nosso aplicativo.

Em seguida, adicionamos uma função addList que adicionará listas quando clicada usando o método .push() para enviar a lista no array que já criamos no array @observable lists .

A função deleteList aceita List como uma propriedade que deve ser o item que o usuário deseja remover. Em seguida, definimos o valor de this.Lists para um novo array após removermos o item selecionado.

Tanto addLists quanto deleteList são ações porque modificam o estado do nosso aplicativo quando são feitas alterações.

Inicializando a Loja MobX

O próximo da nossa lista é importar nossa loja em nosso App.js e usá-la em nosso projeto.

 import React from 'react'; import Navbar from "./components/navbar"; import ListDisplay from "./components/ListDisplay"; import {ListStore} from './ListStore'; function App() { const store = new ListStore() return ( <div> <Navbar store={store}/> <ListDisplay store={store}/> </div> ); } export default App;

Aqui importamos os componentes TitleInput e ListDisplay . Em seguida, inicializamos a loja em nosso App.js para poder passá-la como props para os componentes TitleInput e ListDisplay .

Normalmente, isso gerará um erro porque não trabalhamos nos outros componentes, então vamos fazer isso. Vamos construir o componente ListDisplay .

ListDisplay

Este componente exibe todas as nossas listas adicionadas e também gera automaticamente um botão de exclusão quando uma nova lista é adicionada.

 import React from 'react' import List from "./List"; import { observer } from 'mobx-react'; function ListDisplay(props) { const { deleteList, filteredLists } = props.store return ( <div> <div className="container"> {filteredLists.map(list => ( <List key={list.id} list={list} deleteList={deleteList} /> ))} </div> </div> ) } export default observer(ListDisplay)

Para este componente, criamos uma função ListDisplay e a tornamos um observador, também desestruturamos as funções list e deletelist do store, fazendo isso, facilitamos a passagem de objetos como props.

Em seguida, mapeamos por filteredLists para retornar as listas, que usamos na construção da lista individual passando o item retornado como props para o componente List .

Uma vez feito, nosso componente deve ficar assim com listas adicionadas:

O componente de exibição de lista
Listas exibidas pelo componente `ListDisplay`. (Visualização grande)

O próximo passo é adicionar os componentes List e TitleInput .

Componente de lista

Assim como nossos outros componentes, nosso componente List exportará a lista como um observador para ajudar a loja a observá-la quanto a alterações.

 import React from 'react' import { observer } from 'mobx-react' function List(props) { return ( <div className="card"> <div className="card-body"> <div className="d-flex justify-content-between align-items-center"> <p className={`title ${props.list.done ? "text-secondary" : ""}`}> {props.list.value} </p> <div> <button onClick={props.deleteList.bind(this, props.list)} className="btn btn-danger font-weight-bold py-2 px-5 ml-2"> Delete </button> </div> </div> </div> </div> ) } export default observer(List)

Usei o bootstrap para criar cartões no primeiro conjunto de divs e também alinhar o ícone de exclusão para mover para o lado direito do aplicativo. Primeiro, criamos um componente de cartão para lidar com nossa list e depois criamos uma tag de botão para o button delete que aceitará dois objetos deste e passará um prop para a lista, isso ao clicar, removerá o item da lista selecionada do listas na página.

O componente de lista
Um único componente de lista com o botão excluir. (Visualização grande)

O próximo é nosso TitleInput que conterá nosso formulário de entrada para adicionar listas e o título do projeto.

TitleInput

Semelhante aos nossos outros projetos, adicionaremos uma função @observer para que o componente possa aceitar adereços da App Store.

 import React, { useState } from 'react' import { observer } from 'mobx-react' function Navbar(props) { const [value, setValue] = useState("") const {addList} = props.store const prepareAddList = (e) => { e.preventDefault() addList(value) setValue("") } return ( <div className="container mt-3"> <h1 className="title">List App</h1> <form onSubmit={prepareAddList} className="form-group"> <div className="row ml-lg-2"> <input className="form-control-lg col-12 col-lg-9 col-sm-12 mr-3 border border-secondary" value={value} type="text" onChange={(e) => setValue(e.target.value)} placeholder="Enter list" /> <button className="col-lg-2 col-5 col-sm-5 mt-2 mt-lg-0 mt-sm-2 btn btn-lg btn-success font-weight-bold"> Add to List </button> </div> </form> </div> ) } export default observer(Navbar)

Primeiro, inicializamos um estado inicial. Usando React Hooks, adicionamos um estado inicial chamado values ​​que definimos como uma string vazia. Usamos isso para manter o valor do que é inserido no campo de entrada. Para saber mais sobre React Hooks, você pode conferir este artigo de David Abiodun.

Em seguida, chamamos um objeto para adicionar listas à loja addList e o passamos como adereços da loja de aplicativos.

Em seguida, criamos uma função preparedAddList para aceitar um objeto de evento para os formulários de entrada, também adicionamos um botão para adicionar as listas manualmente ao clicar.

Quase pronto, precisamos reiniciar nosso servidor de projeto executando:

 yarn start

E nosso TitleInput deve ficar assim:

Uma entrada de título
Título e componente de entrada. (Visualização grande)

Concluímos agora todos os componentes do nosso aplicativo, então vamos montá-lo em nosso App.js . Para fazer isso, precisamos importar nossos componentes titleInput e ListDisplay . Também precisamos importar nossa loja do componente Store.

Para que o MobX funcione em nosso App, precisamos passar a loja MobX como props em nosso App e componentes individuais para que eles obtenham as propriedades e funções na loja.

 import React from 'react'; import Navbar from "./components/navbar"; import ListDisplay from "./components/ListDisplay"; import {ListStore} from './ListStore'; function App() { const store = new ListStore() return ( <div> <Navbar store={store}/> <ListDisplay store={store}/> </div> ); } export default App;

Nosso aplicativo deve ficar assim quando concluído:

Aplicativo de lista completa
(Visualização grande)

Conclusão

MobX é um ótimo gerenciador de estado especialmente para aplicativos baseados em React, construindo nosso aplicativo de lista, aprendemos os conceitos básicos do MobX, estado, derivações e ações. Uma versão funcional deste aplicativo pode ser encontrada aqui:

Você pode levar isso adiante usando o MobX no próximo aplicativo que você criar que envolva o gerenciamento de estado. Eu adoraria ver que coisas novas você inventa. Você pode ler mais sobre MobX e aplicativos de gerenciamento de estado nas referências abaixo.

Recursos e referências

  • “React Native with MobX – Getting Started,” Nader Dabit, Medium
  • “Conceitos e Princípios” MobX (documentação oficial)
  • “Melhores práticas com ganchos de reação”, Adeneye David Abiodun, Smashing Magazine