Estimated reading time: 3 minutes

Managing state in ReactJS

Managing state in is crucial for building dynamic and interactive user interfaces. Here’s a breakdown of the common approaches, from simple to more complex:

1. useState Hook (Functional Components):

  • This is the most fundamental way to manage state in functional components.
  • It allows you to declare state variables and update them.

JavaScript

import React, { useState } from 'react';

function MyComponent() {
  const [count, setCount] = useState(0);

  const increment = () => {
    setCount(count + 1);
  };

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}
  • useState(0)1 initializes the count state variable to 0.
  • setCount is a function that lets you update the count state.

2. Class Component this.state (Class Components):

  • Before hooks, class components used this.state to manage state.

JavaScript

import React, { Component } from 'react';

class MyComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }

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

  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={this.increment}>Increment</button>
      </div>
    );
  }
}
  • this.state initializes the state.
  • this.setState() updates the state.

3. useReducer Hook (Complex State):

  • useReducer is useful for managing more complex state logic, especially when state updates depend on previous state or involve multiple sub-values.
  • It’s similar to Redux’s reducer concept.

JavaScript

import React, { useReducer } from 'react';

const initialState = { count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    default:
      return state;
  }
}

function MyComponent() {
  const &lsqb;state, dispatch] = useReducer(reducer, initialState);

  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
    </div>
  );
}
  • A reducer function specifies how state should change based on actions.
  • dispatch sends actions to the reducer.

4. Context (Global State):

  • The Context API allows you to share state between components without explicitly passing props through every level of the component tree.2
  • It’s suitable for application-wide state (e.g., themes, user authentication).

JavaScript

import React, { createContext, useContext, useState } from 'react';

const CountContext = createContext();

function CountProvider({ children }) {
  const &lsqb;count, setCount] = useState(0);

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

function MyComponent() {
  const { count, setCount } = useContext(CountContext);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}
  • createContext3 creates a context object.
  • CountContext.Provider provides the state to components.
  • useContext consumes the context value.

5. Redux/Zustand/Recoil (Complex Global State):

  • For very large and complex applications, state management libraries like Redux, Zustand, or Recoil can be beneficial.
  • They provide a centralized store for managing application-wide state and enforce a predictable state update pattern.
  • Zustand and Recoil are generally considered easier to implement than Redux.

Choosing the Right Approach:

  • For simple component-level state, useState is usually sufficient.
  • For complex component-level state, useReducer can be helpful.
  • For sharing state between components without prop drilling, the Context API is a good option.
  • For very large and complex applications with global state, consider a state management library like Redux, Zustand or Recoil.

Agentic AI (45) AI Agent (35) airflow (6) Algorithm (35) Algorithms (88) apache (57) apex (5) API (135) Automation (67) Autonomous (60) auto scaling (5) AWS (73) aws bedrock (1) Azure (47) BigQuery (22) bigtable (2) blockchain (3) Career (7) Chatbot (23) cloud (143) cosmosdb (3) cpu (45) cuda (14) Cybersecurity (19) database (138) Databricks (25) Data structure (22) Design (113) dynamodb (10) ELK (2) embeddings (39) emr (3) flink (12) gcp (28) Generative AI (28) gpu (25) graph (49) graph database (15) graphql (4) image (50) indexing (33) interview (7) java (43) json (79) Kafka (31) LLM (59) LLMs (55) Mcp (6) monitoring (128) Monolith (6) mulesoft (4) N8n (9) Networking (16) NLU (5) node.js (16) Nodejs (6) nosql (29) Optimization (91) performance (193) Platform (121) Platforms (96) postgres (5) productivity (31) programming (54) pseudo code (1) python (110) pytorch (22) Q&A (2) RAG (65) rasa (5) rdbms (7) ReactJS (1) realtime (2) redis (16) Restful (6) rust (3) salesforce (15) Spark (39) sql (70) tensor (11) time series (17) tips (14) tricks (29) use cases (93) vector (60) vector db (9) Vertex AI (23) Workflow (67)