Recentemente encontrei um vídeo muito bom falando sobreArquitetura MVVM no React Native. Realmente é um assunto que não é muito abordado na comunidade React/React-Native. O que acaba tornando o conteúdo abordado de grande importância.
Portanto, a proposta deste conteúdo é trazer um complemento sobre a abordagem do Padrão de ArquiteturaMVVM utilizando o Padrão de ProjetoFactory.
Diferente doMVP (Model-View-Presenter), oMVVM (Model-View-ViewModel) traz uma proposta onde deixamos o tratamento das informações para o ViewModel, um pouco parecido com o Presenter. No entanto, a grande diferença é, enquanto o Presenter do MVP conhece a View e tem o papel de "apresentar". No MVVM o ViewModel tem o papel de também conter o tratamento das informações, porém, ele não conhece a View, ocorrendo o contrário, a View conhecendo o ViewModel, ou vários ViewModel's.
Feita a introdução, vamos ao ponto que eu quero chegar. É comum "injetarmos" o ViewModel diretamente na nossa View utilizando o MVVM. E isso me incomoda um pouco, portanto, vamos utilizar o padrão de projeto Factory para desacoplarmos a implementação do ViewModel da nossa View.
Eu aproveitei o excelente conteúdo apresentado no video e fiz um fork dorepositório para realizarmos as nossas alterações.
A primeira coisa a ser feita é removermos ouseLoginViewModel que estava sendo usado diretamente dentro da nossa View. Como podemos ver no código abaixo:
importuseLoginViewModelfrom'./view.model';constLoginView:React.FC=()=>{const{email,password,setEmail,setPassword,isLoading,onSubmit}=useLoginViewModel();};
Vamos receber o loginViewModel via props, como o useLoginViewModel retornava o tipoLoginViewModel, então a alteração será mínima. Portanto:
- Recebemos loginViewModel via props;
constLoginView:React.FC<Props>=({loginViewModel})=>{const{email,password,setEmail,setPassword,isLoading,onSubmit}=loginViewModel;};
- Agora vamos definir um tipo para o loginViewModel, como já mencionado o useLoginViewModel retornava um tipo LoginViewModel, logo:
typeProps={loginViewModel:LoginViewModel;};
Bem, isso feito. Vamos criar o nossoFactory que vai realizar a composição das dependências, ou seja, vamos passar o nosso loginViewModel via props para a nossa View.
importReactfrom'react';importLoginViewfrom'../../../pages/login/view';importuseLoginViewModelfrom'../../../pages/login/view.model';constloginViewFactory:React.FC=()=>{constloginViewModel=useLoginViewModel();return<LoginViewloginViewModel={loginViewModel}/>;};exportdefaultloginViewFactory;
Por fim, agora basta usar o nossoLoginFactory na raiz do App, em vez do LoginView.
importReactfrom'react';importLoginFactoryfrom'./helpers/factories/login/view.factory';constApp:React.FC=()=>{return<LoginFactory/>;};exportdefaultApp;
E é isso pessoal, com essa abordagem, conseguimos desacoplar da nossa View o ViewModel, passando apenas o tipo LoginViewModel via props, deixando totalmente independente da implementação utilizando um Factory. Ah, e os testes estão passando normalmente sem necessidade de alterações.
Caso tenha interesse em ver o código:https://github.com/MarlonBeloMarques/mvvm-factory-with-react-native
Valeu galera, até a próxima.
Top comments(5)

Bacana a abordagem, porém passar os hooks diretamente para uma única view vejo que teria renders desnecessários, sempre que ologinViewModel for alterado o seuLoginView irá renderizar toda a árvore, ou seja qualquer alteração que houver do hook
constloginViewModel=useLoginViewModel();
Irá renderizar tudo dentro do LoginView.

- LocationGramado, Rio Grande do Sul
- EducationUERR
- WorkRiachuelo
- Joined
Sim, realmente é um ponto a se considerar. Porém, se fossemos usar diretamente dentro da View, o impacto seria o mesmo, não? Talvez refinando melhor a ideia, acredito que chegamos em uma solução melhor.

Se for usado diretamente dentro da View dependendo de como fossse feito teriamos o mesmo problema mesmo, porém se fosse usado um useMemo por exemplo, dessa forma tendo uma única View não funcionária, pq temos uma única prop responsável por todas as props.

- LocationGramado, Rio Grande do Sul
- EducationUERR
- WorkRiachuelo
- Joined
Exatamente, realmente é algo que pode ser investigado para ver se serial possível com essa abordagem de ViewModel.
For further actions, you may consider blocking this person and/orreporting abuse