React Native with MVVM

November 22, 2021 Publish By : EXPERT APP DEVS 7 min read Viewed By : 61
react native with mvvm

Introduction -

If you have ever experienced the situation, when you open the code you see an unmaintainable and unstructured code, and you are also afraid to touch the code because maybe it crashed.

Javascript is easy to pick up and start coding with it but when you have a small project it’s ok you can manage it by any way but when it comes to a big project managing it in a good way is very important.

So we apply the MVVM(Model-View-ViewModel) pattern architecture in our react native project.

model-view-viewmodel

Architecture Pattern - is a combination of predefined systems with their specific responsibility and it also has guidelines which organize the system.

Some other architectural patterns also try to solve the same problem as MVVM done, you can check others too which handle the code loosely coupled, maintainable and easy to test as well.

Some Questions - may be in your mind there are some questions like if you know the redux and flux then why you need to learn one more architectural pattern, and this is a very genuine question.

And the answer is if you don’t know the other then how could you compare it, how you know the reduc is best and it fits for all your project so first, you need to try some other architecture too.

MVVM Blocks -

MVVM has 4 main blocks, we describe these as following.

  • View - View is a UI layer, which users interact most with. 
  • ViewController - It handles the user inputs and has access to ViewModal as well.
  • ViewModel - It handles the business logic and has access to modal as well.
  • Model - this is the main data source of the application.

MVVM Component-

mvvm component

So let’s start with the description of these blocks in detail.

View -

In react native for user interaction we build the UI, which most of you are familiar with and also the way how we implement this in our project.

View is the only point where users can interact with your applications. When the user touches anything in interaction with the view controller that is handled by any events such as key press, mouse movement, etc.

It is also used for showing the output to the user based on the input which user gave.

React.Component is a reactive component which handles everything in every possible way and updates the changes automatically.

 Syntax - 

import React from 'react'

class PokemonView extends React.Component {
   render() {
       const {
           pokemons,
           pokemonImage,
           pokemonName,
           randomizePokemon,
           setPokemonName,
           addPokemon,
           removePokemon,
           shouldDisableSubmit
       } = this.props

       return (
           <React.Fragment>
               <PokemonForm
                   image={pokemonImage}
                   onInputChange={setPokemonName}
                   inputValue={pokemonName}
                   randomize={randomizePokemon}
                   onSubmit={addPokemon}
                   shouldDisableSubmit={shouldDisableSubmit}
               />
               <PokemonList
                   removePokemon={removePokemon}
                   pokemons={pokemons}
               />
           </React.Fragment>
       )
   }
}

export default PokemonView

ViewController -

The viewcontroller is the main part of a view and it has all view-related logic and it also references the View modal as well.
Also, view is not much aware with ViewModal, it is a basic relay with the viewController to pass all events and data. And if we talk about the relation between viewcontroller and view modal then it is a one-to-many relation.

Syntax -

​​import React from 'react'
import PokemonView from './PokemonView'

class PokemonController extends React.Component {
   state = {
       pokemonImage: '1.gif',
       pokemonName: ''
   }

   setRandomPokemonImage = () => {
       const rand = Math.ceil(Math.random() * 10)
       this.setState({ pokemonImage: `${rand}.gif` })
   }

   setPokemonName = (e) => {
       this.setState({ pokemonName: e.target.value })
   }

   clearPokemonName() {
       this.setState({ pokemonName: '' })
   }

   savePokemon = () => {
       this.props.viewModel.addPokemon({
           image: this.state.pokemonImage,
           name: this.state.pokemonName
       })
   }

   addPokemon = () => {
       this.savePokemon()
       this.clearPokemonName()
   }

   removePokemon = (pokemon) => {
       this.props.viewModel.removePokemon(pokemon)
   }

   render() {
       const { viewModel } = this.props

       return (
           <PokemonView
               pokemons={viewModel.getPokemons()}
               pokemonImage={this.state.pokemonImage}
               randomizePokemon={this.setRandomPokemonImage}
               setPokemonName={this.setPokemonName}
               addPokemon={this.addPokemon}
               removePokemon={this.removePokemon}
               pokemonName={this.state.pokemonName}
               shouldDisableSubmit={!this.state.pokemonName}
           />
       )
   }
}

export default PokemonController

ViewModal - 

If we talk about ViewModal then this one is a producer and it doesn’t care about who is a consumer of that data.

It can be a vue component, react component and any other component too, it does not care about it.

Because ViewModal is just a regular javascript and you can use it anywhere you want or you can re-use it as well according to your UI conditions.

Which dependency is needed by the ViewModal we can inject that with the constructor so it is easy to make and test.

Syntax -

class PokemonViewModel {
   constructor(pokemonStore) {
       this.store = pokemonStore
   }

   getPokemons() {
       return this.store.getPokemons()
   }

   addPokemon(pokemon) {
       this.store.addPokemon(pokemon)
   }

   removePokemon(pokemon) {
       this.store.removePokemon(pokemon)
   }
}

export default PokemonViewModel

Modal - 

Modal is basically the store of your application and it acts as the main data source in your app.

It takes all data from the network layer, database, and from services then serves it to the application in a very easy way.

It basically updates the modal and handles all modal related changes too. 

Syntax -

import { observable, action } from 'mobx'
import uuid from 'uuid/v4'

class PokemonModel {
   @observable pokemons = []

   @action addPokemon(pokemon) {
       this.pokemons.push({
           id: uuid(),
           ...pokemon
       })
   }

   @action removePokemon(pokemon) {
       this.pokemons.remove(pokemon)
   }

   @action clearAll() {
       this.pokemons.clear()
   }

   getPokemons() {
       return this.pokemons
   }
}

export default PokemonModel

That’s it, I think you like the blog and information which you take from this blog, and if you have any queries related to react native app development please feel free to ask.

Happy Coding.

Need a consultation?

Drop us a line! We are here to answer your questions 24/7.