Understanding State and Lifecycle in React

When building interactive UIs with React, two core concepts you must understand are state and lifecycle. These are what make React components dynamic, interactive, and responsive.

In this post, we’ll explore:

  • What state is in React
  • How lifecycle methods work
  • The difference between class and functional components
  • How to use hooks like useState and useEffect

What is State in React?

In React, state refers to data that changes over time. It is managed within a component and can influence what gets rendered on the screen.

When the state of a component updates, React re-renders that component automatically.

Example: A Simple Counter Using useState

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0); // Declare state variable

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click Me
      </button>
    </div>
  );
}

useState(0) initializes the state with 0.

setCount is the function used to update the state.

React re-renders the component every time count changes.

Understanding Lifecycle in React

Every React component goes through a lifecycle:

  1. Mounting – Component is being inserted into the DOM.
  2. Updating – Component updates due to changes in state or props.
  3. Unmounting – Component is removed from the DOM.

These phases allow us to hook into key moments of a component’s existence.

Lifecycle Methods in Class Components

React class components come with lifecycle methods that allow you to run code at specific times.

MethodDescription
componentDidMount()Runs after the component is added to the DOM
componentDidUpdate()Runs after an update happens
componentWillUnmount()Runs before the component is removed

Example: Timer Component Using Class

class Timer extends React.Component {
  constructor(props) {
    super(props);
    this.state = { seconds: 0 };
  }

  componentDidMount() {
    this.interval = setInterval(() => {
      this.setState(prev => ({ seconds: prev.seconds + 1 }));
    }, 1000);
  }

  componentWillUnmount() {
    clearInterval(this.interval);
  }

  render() {
    return <p>Seconds: {this.state.seconds}</p>;
  }
}

Lifecycle in Functional Components with Hooks

With React Hooks, you can achieve the same lifecycle behavior in functional components using the useEffect hook.

Example: Timer with useEffect

import React, { useState, useEffect } from 'react';

function Timer() {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setSeconds(prev => prev + 1);
    }, 1000);

    return () => clearInterval(interval); // Cleanup on unmount
  }, []);

  return <p>Seconds: {seconds}</p>;
}

useEffect with an empty dependency array ([]) acts like componentDidMount.
The return function handles cleanup, similar to componentWillUnmount.

State vs Props: Key Differences

FeatureStateProps
Owned byThe component itselfThe parent component
MutabilityMutableImmutable
UsageManage local dataPass data to child components

Why Are State and Lifecycle Important?

Mastering state and lifecycle is essential to:

  • Build dynamic interfaces
  • Handle asynchronous events
  • Manage API calls
  • Optimize performance with controlled re-renders
  • Avoid memory leaks with proper cleanup

Related Concepts to Explore

  • React Context for global state
  • Custom hooks for reusable logic
  • React Router for navigation
  • Performance optimization with React.memo and useCallback

Final Thoughts

React is powerful because it reacts to state changes and renders UI dynamically. To build responsive and maintainable applications, understanding state and lifecycle is non-negotiable.

Whether you’re using class components or modern functional components with hooks, these tools are the foundation of every interactive React app.