Aqui na Cubos, para desenvolvimento de sites, utilizamos React e Mobx no front end. React, por ser uma biblioteca que permite criar interfaces muito mais vivas e próximas de um aplicativo, gerando um resultado melhor, e mantendo o código muito bem estruturado e reutilizável. Mobx, por ser uma forma prática e simples de lidar e mover dados de um lugar para o outro pelo React.

Quando comecei a desenvolver em React, logo me veio a necessidade de manter minhas mudanças de estado controladas, sem a necessidade de varrer o código todo para certos componentes serem renderizados quando necessário. Então, eu conheci o Redux; com um grande boilerplate e uma curva de aprendizado não tão pequena, tive um péssimo primeiro contato com essa biblioteca. Na Cubos, conheci o Mobx, que, em relação ao Redux, possui um tamanho ínfimo de código para fazer algo funcionar.

Enfim, logo me encantei pela biblioteca e comecei a utilizar em todos meus projetos. Com um tempo acabei percebendo um grande problema: a falta de boas práticas com projetos em Mobx. O Redux pode ter um grande boilerplate, mas é mais difícil escrever com más práticas, logo, mas fácil ter um código bem organizado. Então resolvi escrever aqui, sobre experiências que eu tive em projetos Mobx e o que não se deve fazer.

bart

1. Mantenha sua lógica na Store

Incontáveis vezes encontrei chamadas da API ou algumas lógicas do fluxo da aplicação diretamente no componente, sendo que as stores foram feitas justamentos para manter o controle dos estados e efetuar as chamadas da API. Veja essa citação retirada diretamente da documentação do Mobx:

The main responsibility of stores is to move logic and state out of your components into a standalone testable unit that can be used in both frontend and backend JavaScript.

Então, mesmo que seja um simples chamada para deletar um usuário, faça na store. Ou se você precisa filtrar uma lista de clientes em função de algo, faça isso na store. Acho que já deu para entender o recado.

2. Não utilize uma ÚNICA Store

Certo, então você entendeu que a lógica da sua aplicação deve estar em suas stores, então pegou todas elas, criou um arquivo store.js e jogou elas lá. Bem… Está ERRADO! Do ponto de vista técnico, pode sim funcionar perfeitamente, mas pense bem: você gostaria de pegar um trabalho já em desenvolvimente e encontrar um arquivo único com várias funções sem você entender quase nada? Já passei por isso e digo que não é nem um pouco interessante.
meme
O interessante aqui é criar várias stores, exemplo: userStore, adminStore, uiStore e um arquivo index onde você pode exportar todas as suas stores e em determinado componente só utilizar as necessárias.

3. Abuse do Observer

Use o observer em todos os componentes que utilizam de observables. Diferente do que muitos acham, e até eu pensava dessa forma, utilizar desses decorators em todos os componentes só melhoram a performance do Mobx, em vez de deixar mais lento. Isso também é explicado na documentação deles:

@observer only enhances the component you are decorating, not the components used inside it. So usually all your components should be decorated. Don't worry, this is not inefficient, in contrast, more observer components make rendering more efficient.

Não só no caso do observer e do observable. Mas também nas stores, utilizar do action e do computed, por exemplo, a performance do mobx com funções computed tem um ganho em sua execução. Para saber um pouco mais disso, é importante ler sobre o autorun.

4. Separe a importação das stores do provider

Lembra como é importante separar bem as stores do resto da sua aplicação? Então qual é a necessidade de seu arquivo index, onde você chama seu componente Provider do react, fazer a importação de uma store sempre que uma nova for adicionada? Não faz mais sentido separar isso? Para isso, crie por exemplo um arquivo no seu diretório de stores que faça a importação de todas suas stores, e lá no Provider você apenas importa esse arquivo e utiliza com o operador spread.

import { Provider } from “mobx-react”;
import RootStore from “./stores/RootStore”;
<Provider {…RootStore} >

E no arquivo RootStore:

import { AuthStore, UIStore} from “./”;
const authStore = new AuthStore();
const uiStore = new UIStore();
export default { authStore, uiStore };

Considerações Finais

Então, esses quatro tópicos que abordei aqui são sobre problemas que passei várias vezes em projetos já em desenvolvimento feitos com mobx. Tive uma dificuldade para entender várias vezes os projetos, além de ter também uma perda de performance no sistema em algumas situações. Ainda há muita coisa a se abordar sobre boas práticas, mas se você tiver mais interesse, dá uma olhada na documentação do mobx, que fala um pouco sobre isso.