Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Marlon Marques
Marlon Marques

Posted on

     

MVVM com Factory no React Native

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();};
Enter fullscreen modeExit fullscreen mode

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;};
Enter fullscreen modeExit fullscreen mode
  • Agora vamos definir um tipo para o loginViewModel, como já mencionado o useLoginViewModel retornava um tipo LoginViewModel, logo:
typeProps={loginViewModel:LoginViewModel;};
Enter fullscreen modeExit fullscreen mode

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;
Enter fullscreen modeExit fullscreen mode

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;
Enter fullscreen modeExit fullscreen mode

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)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
colaquecez profile image
Filipe Colaquecez
  • Joined
• Edited on• Edited

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();
Enter fullscreen modeExit fullscreen mode

Irá renderizar tudo dentro do LoginView.

CollapseExpand
 
marlonbelomarques profile image
Marlon Marques
Mobile Developer | React Native | Enthusiast of TDD and Clean Architecture
  • Location
    Gramado, Rio Grande do Sul
  • Education
    UERR
  • Work
    Riachuelo
  • 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.

CollapseExpand
 
colaquecez profile image
Filipe Colaquecez
  • Joined

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.

Thread Thread
 
marlonbelomarques profile image
Marlon Marques
Mobile Developer | React Native | Enthusiast of TDD and Clean Architecture
  • Location
    Gramado, Rio Grande do Sul
  • Education
    UERR
  • Work
    Riachuelo
  • Joined
• Edited on• Edited

Exatamente, realmente é algo que pode ser investigado para ver se serial possível com essa abordagem de ViewModel.

Thread Thread
 
colaquecez profile image
Filipe Colaquecez
  • Joined

Sim total, no nativo temos essas facilidades, talvez irá ter uma evolução no React que nos permita aplicar essas arquiteturas.

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Mobile Developer | React Native | Enthusiast of TDD and Clean Architecture
  • Location
    Gramado, Rio Grande do Sul
  • Education
    UERR
  • Work
    Riachuelo
  • Joined

More fromMarlon Marques

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp