DEV Community

Cover image for State Management in React Native: Redux, Context API, MobX, and Zustand
Paulo Messias
Paulo Messias

Posted on

State Management in React Native: Redux, Context API, MobX, and Zustand

Hey devs!

Managing state in React Native applications is crucial for ensuring a consistent and efficient user experience. There are various libraries and approaches available to facilitate this process, each with its own strengths and specific use cases. In this article, we will explore the key differences between Redux, Context API, MobX, and Zustand, highlighting their strengths, code examples, and how to apply them to your project.

Redux

Redux is a predictable state management library for JavaScript, widely adopted in the React Native community. It centralizes the application state in a single store, making it easier to trace and maintain.

Strengths

  • Predictability: Centralized state that facilitates tracing and debugging.
  • DevTools: Redux DevTools for state inspection and manipulation.
  • Community and Support: Large community and extensive documentation.

Weaknesses

  • Complexity: Requires significant setup and boilerplate.
  • Learning Curve: Can be challenging for beginners due to its robust structure.

Code Example

store.js

// store.js
import { createStore } from 'redux';

// action types
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';

// actions
export const increment = () => ({ type: INCREMENT });
export const decrement = () => ({ type: DECREMENT });

// reducer
const initialState = { count: 0 };
const counterReducer = (state = initialState, action) => {
  switch (action.type) {
    case INCREMENT:
      return { count: state.count + 1 };
    case DECREMENT:
      return { count: state.count - 1 };
    default:
      return state;
  }
};

// store
export const store = createStore(counterReducer);
Enter fullscreen mode Exit fullscreen mode

App.js

// App.js
import React from 'react';
import { Provider, useSelector, useDispatch } from 'react-redux';
import { store, increment, decrement } from './store';

const Counter = () => {
  const count = useSelector(state => state.count);
  const dispatch = useDispatch();

  return (
    <div>
      <p>{count}</p>
      <button onClick={() => dispatch(increment())}>Increment</button>
      <button onClick={() => dispatch(decrement())}>Decrement</button>
    </div>
  );
};

const App = () => (
  <Provider store={store}>
    <Counter />
  </Provider>
);

export default App;
Enter fullscreen mode Exit fullscreen mode

Context API

The Context API is a React native solution for passing data through the component tree without having to manually pass props at each level.

Strengths

  • Native: An integral part of React, no need for external dependencies.
  • Simplicity: Easy to use for simple cases of state management.

Weaknesses

  • Performance: Can cause unnecessary renderings if not used properly.
  • Scalability: Less suitable for large applications with many complex states.

Code Example

CountContext.js

// CountContext.js
import React, { createContext, useState, useContext } from 'react';

const CountContext = createContext();

export const CountProvider = ({ children }) => {
  const [count, setCount] = useState(0);
  const increment = () => setCount(count + 1);
  const decrement = () => setCount(count - 1);

  return (
    <CountContext.Provider value={{ count, increment, decrement }}>
      {children}
    </CountContext.Provider>
  );
};

export const useCount = () => useContext(CountContext);
Enter fullscreen mode Exit fullscreen mode

App.js

// App.js
import React from 'react';
import { CountProvider, useCount } from './CountContext';

const Counter = () => {
  const { count, increment, decrement } = useCount();

  return (
    <div>
      <p>{count}</p>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
    </div>
  );
};

const App = () => (
  <CountProvider>
    <Counter />
  </CountProvider>
);

export default App;
Enter fullscreen mode Exit fullscreen mode

MobX

MobX is a library that allows reactive state management, where components are automatically updated when the state changes.

Strengths

  • Reactivity: Automatic updates based on state changes.
  • Simplicity: Less boilerplate compared to Redux for reactive states.

Weaknesses

  • Magic: Can be less predictable due to its reactive nature.
  • Adoption: Less adopted compared to Redux, resulting in fewer resources and tools available.

Code Example

store.js

// store.js
import { makeAutoObservable } from 'mobx';

class CounterStore {
  count = 0;

  constructor() {
    makeAutoObservable(this);
  }

  increment = () => {
    this.count += 1;
  };

  decrement = () => {
    this.count -= 1;
  };
}

export const counterStore = new CounterStore();
Enter fullscreen mode Exit fullscreen mode

App.js

// App.js
import React from 'react';
import { observer } from 'mobx-react';
import { counterStore } from './store';

const Counter = observer(() => (
  <div>
    <p>{counterStore.count}</p>
    <button onClick={counterStore.increment}>Increment</button>
    <button onClick={counterStore.decrement}>Decrement</button>
  </div>
));

const App = () => (
  <div>
    <Counter />
  </div>
);

export default App;
Enter fullscreen mode Exit fullscreen mode

Zustand

Zustand is a lightweight and simple state management library for React, offering high performance and an intuitive API.

Strengths

  • Simplicity: Simple and easy-to-understand API.
  • Performance: High performance with optimized renderings.
  • Size: Lightweight with minimal overhead.

Weaknesses

  • Community: Less adoption compared to Redux and Context API.
  • Documentation: Less extensive compared to more established libraries.

Code Example

useStore.js

// useStore.js
import create from 'zustand';

const useStore = create(set => ({
  count: 0,
  increment: () => set(state => ({ count: state.count + 1 })),
  decrement: () => set(state => ({ count: state.count - 1 })),
}));

export default useStore;
Enter fullscreen mode Exit fullscreen mode

App.js

// App.js
import React from 'react';
import useStore from './useStore';

const Counter = () => {
  const { count, increment, decrement } = useStore();

  return (
    <div>
      <p>{count}</p>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
    </div>
  );
};

const App = () => (
  <div>
    <Counter />
  </div>
);

export default App;
Enter fullscreen mode Exit fullscreen mode

Each of the presented libraries — Redux, Context API, MobX, and Zustand — offers a unique way to manage state in React Native applications. The choice between them depends on your project's specific needs, such as complexity, performance, and personal preferences. I hope this guide has helped you better understand your options and make informed decisions when choosing a state management solution for your React Native projects.

References

  1. Redux
  2. React Context API
  3. MobX
  4. Zustand

Top comments (0)