React Js

React JS Tutorial Learn React JS, the powerful JavaScript library for building dynamic and interactive user interfaces. This beginner-friendly tutorial covers core concepts like components, state, props, and hooks, with hands-on projects to create responsive web apps. Perfect for aspiring developers looking to master modern front-end development.

React Class Components

24 April 2025 | Category:

Welcome to this beginner-friendly tutorial on React Class Components! Class components are a traditional way to build React applications, using ES6 classes to create reusable UI elements with state and lifecycle methods. While functional components with hooks are now preferred, class components are still relevant for maintaining legacy code or specific use cases. In this guide, you’ll learn how to create class components, manage state and props, use lifecycle methods, and handle events. We’ll build a Movie Rating App that displays movies and allows users to rate them. By the end, you’ll understand class components and be ready to work with them in React.


What are Class Components?

A React class component is an ES6 class that extends React.Component and includes a render method to return JSX, defining the component’s UI. Class components can manage state, handle props, and use lifecycle methods to control behavior at different stages of a component’s life (e.g., mounting, updating, unmounting).

Why Learn Class Components?

  • Legacy Code: Many older React projects use class components, so understanding them is essential for maintenance.
  • Lifecycle Methods: Class components provide fine-grained control over a component’s lifecycle, useful for specific scenarios.
  • Foundation: Learning class components deepens your understanding of React’s core concepts.
  • Transition to Hooks: Knowing class components helps you appreciate why hooks were introduced.

Prerequisites

Before starting, you should have:

  • Basic knowledge of React (JSX, props) and JavaScript (ES6 classes, objects).
  • Node.js and npm installed (download from nodejs.org).
  • A code editor like Visual Studio Code.
  • A terminal for running commands.

We’ll use Create React App to set up our project, which supports JSX, ES6, and React 19 out of the box.


Key Class Component Concepts

Let’s explore the core features of class components.

1. Class Component Syntax

A class component is defined as an ES6 class that extends React.Component and implements a render method.

Example:

import React from 'react';

class Welcome extends React.Component {
  render() {
    return <h1>Hello, React!</h1>;
  }
}

2. Props

Props are read-only inputs passed to a component, accessed via this.props.

Example:

class Movie extends React.Component {
  render() {
    return <h2>{this.props.title}</h2>;
  }
}

// Usage
<Movie title="Inception" />

3. State

State is a component’s internal data, managed via this.state and updated with this.setState.

Example:

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

  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Increment
        </button>
      </div>
    );
  }
}

4. Lifecycle Methods

Lifecycle methods are special methods that run at specific points in a component’s life:

  • Mounting: constructor, componentDidMount
  • Updating: componentDidUpdate
  • Unmounting: componentWillUnmount

Example:

class Timer extends React.Component {
  componentDidMount() {
    console.log('Component mounted!');
  }

  render() {
    return <p>Timer Component</p>;
  }
}

5. Event Handling

Event handlers are methods bound to this in the constructor to ensure proper context.

Example:

class Button extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    alert('Button clicked!');
  }

  render() {
    return <button onClick={this.handleClick}>Click Me</button>;
  }
}

Setting Up the Project

Let’s create a React app to build our Movie Rating App, which will use class components to display and rate movies.

  1. Create a New React App:
    Open your terminal and run: npx create-react-app movie-rating-app cd movie-rating-app
  2. Start the Development Server: npm start This opens your app at http://localhost:3000.
  3. Clean Up:
    Open src/App.js and replace its content with: import React from 'react'; class App extends React.Component { render() { return ( <div> <h1>Movie Rating App</h1> </div> ); } } export default App; Delete src/App.css, src/logo.svg, and update src/index.css with: body { font-family: Arial, sans-serif; margin: 0; padding: 20px; background-color: #f5f5f5; } h1 { color: #333; }

Building the Movie Rating App

Our Movie Rating App will:

  • Display a list of movies using a Movie class component.
  • Allow users to rate movies (1–5 stars) and update state.
  • Include a MovieForm class component to add new movies.
  • Use lifecycle methods to log component updates.

Step 1: Create the Movie Component

  1. In src, create a file named Movie.js:import React from 'react'; class Movie extends React.Component { constructor(props) { super(props); this.state = { rating: props.rating || 0 }; this.handleRating = this.handleRating.bind(this); } handleRating(newRating) { this.setState({ rating: newRating }); } render() { const { title, director } = this.props; const { rating } = this.state; return ( <div style={{ backgroundColor: '#fff', padding: '15px', margin: '10px 0', borderRadius: '8px', boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)', maxWidth: '400px' }}> <h3>{title}</h3> <p>Director: {director}</p> <p>Rating: {rating} / 5</p> <div> {[1, 2, 3, 4, 5].map((star) => ( <button key={star} onClick={() => this.handleRating(star)} style={{ backgroundColor: star <= rating ? '#ffc107' : '#e0e0e0', border: 'none', padding: '5px', margin: '2px', borderRadius: '4px' }} > ★ </button> ))} </div> </div> ); } } export default Movie;
    • Features:
      • Class component with state (rating) initialized from props.
      • Binds handleRating in the constructor to update state.
      • Renders movie details and a star-rating system using JSX.
      • Destructures props and state for cleaner code.

Step 2: Create the MovieForm Component

  1. In src, create a file named MovieForm.js:import React from 'react'; class MovieForm extends React.Component { constructor(props) { super(props); this.state = { title: '', director: '' }; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(e) { this.setState({ [e.target.name]: e.target.value }); } handleSubmit(e) { e.preventDefault(); const { title, director } = this.state; if (title.trim() && director.trim()) { this.props.onAddMovie({ title, director, rating: 0 }); this.setState({ title: '', director: '' }); } } render() { const { title, director } = this.state; return ( <form onSubmit={this.handleSubmit} style={{ marginBottom: '20px' }}> <div style={{ marginBottom: '10px' }}> <input type="text" name="title" value={title} onChange={this.handleChange} placeholder="Movie title" style={{ padding: '8px', width: '200px', borderRadius: '4px' }} /> </div> <div style={{ marginBottom: '10px' }}> <input type="text" name="director" value={director} onChange={this.handleChange} placeholder="Director" style={{ padding: '8px', width: '200px', borderRadius: '4px' }} /> </div> <button type="submit" style={{ padding: '8px 16px', backgroundColor: '#28a745', color: '#fff', border: 'none', borderRadius: '4px' }} > Add Movie </button> </form> ); } } export default MovieForm;
    • Features:
      • Class component with state for form inputs (title, director).
      • Binds handleChange and handleSubmit in the constructor.
      • Uses computed property names ([e.target.name]) to update state dynamically.
      • Passes new movie data to the parent via onAddMovie prop.

Step 3: Update the App Component

  1. Update src/App.js to manage the movie list and use lifecycle methods:import React from 'react'; import Movie from './Movie'; import MovieForm from './MovieForm'; class App extends React.Component { constructor(props) { super(props); this.state = { movies: [ { title: 'Inception', director: 'Christopher Nolan', rating: 4 }, { title: 'The Matrix', director: 'Wachowski Sisters', rating: 3 } ] }; this.addMovie = this.addMovie.bind(this); } componentDidMount() { console.log('App mounted with', this.state.movies.length, 'movies'); } componentDidUpdate(prevProps, prevState) { if (prevState.movies.length !== this.state.movies.length) { console.log('Movie list updated:', this.state.movies); } } addMovie(newMovie) { this.setState((prevState) => ({ movies: [...prevState.movies, newMovie] })); } render() { const { movies } = this.state; return ( <div> <h1>Movie Rating App</h1> <MovieForm onAddMovie={this.addMovie} /> <div> {movies.length > 0 ? ( movies.map((movie, index) => ( <Movie key={index} title={movie.title} director={movie.director} rating={movie.rating} /> )) ) : ( <p>No movies yet. Add one!</p> )} </div> </div> ); } } export default App;
    • Features:
      • Class component with state (movies) and lifecycle methods (componentDidMount, componentDidUpdate).
      • Binds addMovie to update the movie list.
      • Uses setState with a function to safely update state.
      • Renders MovieForm and a list of Movie components with conditional JSX.

Step 4: Test the App

  • Save all files and ensure the development server is running (npm start).
  • Open http://localhost:3000. You should see:
    • Two initial movie cards for “Inception” and “The Matrix” with star ratings.
    • A form to add new movies with title and director fields.
    • The ability to rate movies by clicking stars (1–5).
  • Try adding a movie (e.g., “Dune” by “Denis Villeneuve”) and rating it. Check the console for lifecycle method logs.

Understanding the Code

Let’s recap how class components power our Movie Rating App:

  • Class Components: App, Movie, and MovieForm are all class components extending React.Component.
  • Props: Movie receives title, director, and rating as props; MovieForm receives onAddMovie.
  • State: App manages the movies list, Movie manages individual rating, and MovieForm manages form inputs.
  • Lifecycle Methods: App uses componentDidMount and componentDidUpdate to log lifecycle events.
  • Event Handling: Methods like handleRating and handleSubmit are bound in constructors to ensure correct this context.
  • JSX: Each component uses JSX to define its UI, with dynamic rendering via props and state.
  • ES6 Features:
    • Class syntax and super for inheritance.
    • Destructuring ({ title, director }).
    • Arrow functions in event handlers (e.g., onClick={() => this.handleRating(star)}).
    • Spread operator ([...prevState.movies, newMovie]).

Best Practices for Class Components

  • Bind Methods in Constructor: Bind event handlers in the constructor to avoid performance issues:constructor(props) { super(props); this.handleClick = this.handleClick.bind(this); }
  • Initialize State Properly: Define this.state in the constructor and call super(props).
  • Use Functional Updates for State: Use setState with a function when updating state based on previous state:this.setState((prevState) => ({ count: prevState.count + 1 }));
  • Avoid Overusing Lifecycle Methods: Only use lifecycle methods for necessary side effects (e.g., fetching data in componentDidMount).
  • Keep Components Focused: Each component should handle one responsibility (e.g., Movie displays and rates a movie).
  • Use PropTypes (Optional): Validate props with PropTypes for better debugging:import PropTypes from 'prop-types'; Movie.propTypes = { title: PropTypes.string.isRequired };

Common Class Component Pitfalls and Fixes

  • Unbound Methods:
    Problem: Event handlers lose this context, causing errors (e.g., this.setState is not a function).
    Fix: Bind methods in the constructor or use arrow functions:handleClick = () => { this.setState({ ... }); };
  • State Mutations:
    Problem: Directly modifying this.state (e.g., this.state.count++) doesn’t trigger re-renders.
    Fix: Always use this.setState.
  • Lifecycle Overuse:
    Problem: Adding complex logic in componentDidUpdate can cause infinite loops.
    Fix: Add conditions to prevent unnecessary updates:componentDidUpdate(prevProps) { if (prevProps.value !== this.props.value) { // Update logic } }
  • Missing Keys in Lists:
    Problem: Rendering lists without key props causes warnings.
    Fix: Add unique key props (e.g., <Movie key={id} />).

Functional Components vs. Class Components

While this tutorial focuses on class components, modern React favors functional components with hooks. Here’s a quick comparison:

  • Syntax: Functional components are simpler (functions vs. classes).
  • State: Functional components use useState/useReducer; class components use this.state/this.setState.
  • Lifecycle: Functional components use useEffect; class components use componentDidMount, etc.
  • Use Case: Use functional components for new code; use class components for legacy code or specific lifecycle needs.

Example (Functional Equivalent of Movie):

const Movie = ({ title, director, rating: initialRating }) => {
  const [rating, setRating] = React.useState(initialRating || 0);
  return (
    <div>
      <h3>{title}</h3>
      <p>Director: {director}</p>
      <p>Rating: {rating} / 5</p>
      <div>
        {[1, 2, 3, 4, 5].map((star) => (
          <button key={star} onClick={() => setRating(star)}>
            ★
          </button>
        ))}
      </div>
    </div>
  );
};

What’s Next?

You’ve built a Movie Rating App using React class components! Here are some next steps:

  • Add Features: Implement a button to delete movies or filter by rating.
  • Learn Hooks: Transition to functional components with useState and useEffect.
  • Explore Lifecycle: Use componentWillUnmount to clean up resources (e.g., timers).
  • Build Another App: Create a task tracker or product catalog with class components.

Practice Challenge

Add a “Reset Rating” button to the Movie component that sets the rating back to 0. Use setState and bind the handler in the constructor.


Resources

Congratulations on mastering React class components! You’re now equipped to work with legacy React code and understand component lifecycles. Keep practicing and happy coding!