Skip to content

Redux vs MobX: Which is better state management library

Redux vs MobX: Which is better state management library

Both Redux vs MobX are state management libraries for React and other front-end frameworks. We will try to understand how both work and which one might be better state management library for your project.

Redux vs MobX Introduction

Redux is a predictable state container for JavaScript apps. It provides a centralized store that holds the entire state tree of an application, which can only be modified by dispatching actions to it. These actions are then handled by pure functions called reducers, which update the state of the store.

MobX, on the other hand, is a reactive state management library that uses observable data structures to automatically update the state of the application whenever a change is made. It allows you to define observables and actions that modify those observables, and any components that depend on those observables will automatically be re-rendered when they change.

One of the main differences between the two libraries is their approach to state management. Redux is based on immutability and explicit updates, which can make it more verbose and difficult to learn, but can also make it easier to reason about the flow of data in an application. MobX, on the other hand, is more flexible and easier to learn, but it can be harder to understand how changes propagate through the application.

Another difference is the way they handle performance. Redux uses a technique called memoization to optimize the performance of the reducers, while MobX uses a reactive model that can automatically optimize performance by only re-rendering components that are affected by changes.

Example of using Redux

Let’s say we have an e-commerce application that allows users to add products to a cart and make purchases. We can use Redux to manage the state of the application, such as the products in the cart, the user’s address, and the payment method.

We would define an initial state object that contains all the relevant data, such as:

const initialState = {
  cart: [],
  address: '',
  paymentMethod: ''
}

We would also define action types and action creators to update the state, such as:

const ADD_TO_CART = 'ADD_TO_CART'

function addToCart(product) {
  return { type: ADD_TO_CART, payload: product }
}

Finally, we would define reducers to handle the actions and update the state accordingly:

function cartReducer(state = initialState.cart, action) {
  switch (action.type) {
    case ADD_TO_CART:
      return [...state, action.payload]
    default:
      return state
  }
}

function addressReducer(state = initialState.address, action) {
  switch (action.type) {
    // handle actions to update the address
  }
}

function paymentReducer(state = initialState.paymentMethod, action) {
  switch (action.type) {
    // handle actions to update the payment method
  }
}

Example of using MobX

Let’s say we have a simple todo list application that allows users to add and remove tasks. We can use MobX to manage the state of the application, such as the list of tasks.

We would define a TodoStore class that contains all the relevant data and actions, such as:

import { makeObservable, observable, action } from 'mobx'

class TodoStore {
  todos = []

  constructor() {
    makeObservable(this, {
      todos: observable,
      addTodo: action,
      removeTodo: action,
    })
  }

  addTodo = (text) => {
    this.todos.push({ id: Date.now(), text })
  }

  removeTodo = (id) => {
    this.todos = this.todos.filter((todo) => todo.id !== id)
  }
}

export default new TodoStore()

We can then use this store in our React components, such as:

import React from 'react'
import { observer } from 'mobx-react'
import todoStore from './todoStore'

const TodoList = observer(() => {
  const handleAddTodo = (e) => {
    e.preventDefault()
    const text = e.target.elements.text.value.trim()
    if (text) {
      todoStore.addTodo(text)
      e.target.elements.text.value = ''
    }
  }

  const handleRemoveTodo = (id) => {
    todoStore.removeTodo(id)
  }

  return (
    <div>
      <form onSubmit={handleAddTodo}>
        <input type="text" name="text" placeholder="Add a task" />
        <button type="submit">Add</button>
      </form>
      <ul>
        {todoStore.todos.map((todo) => (
          <li key={todo.id}>
            {todo.text}{' '}
            <button onClick={() => handleRemoveTodo(todo.id)}>Remove</button>
          </li>
        ))}
      </ul>
    </div>
  )
})

export default TodoList

In this example, we use the observer higher-order component from mobx-react to automatically re-render the component whenever the todos array in the TodoStore changes.

Conclusion

In summary, both Redux vs MobX provide powerful tools for managing the state of a React application. Redux can be a good choice for larger and more complex applications that require a strict flow of data, while MobX can be a better fit for smaller and simpler applications that need more flexibility and ease of use.

It’s worth noting that there are other state management libraries available for React, such as Recoil and Zustand, each with their own advantages and disadvantages. The choice of library ultimately depends on the specific needs and requirements of the project.

Regardless of the library chosen, using a state management library can greatly improve the maintainability and scalability of a React application by keeping the state organized and consistent across different components.

Further Reading

How to use React Memo: Actually improve page performance

Please share