Understanding useContext in Class Components

Understanding useContext in Class Components
9 min read
11 September 2023

React's Context API, combined with the useContext hook, has become a powerful tool for managing state and providing data to components deep within the component tree. While it's most commonly used in functional components, you can also leverage useContext in class components. In this comprehensive guide, we'll explore how to use useContext in class components, discuss its benefits, and provide practical examples to help you integrate this feature seamlessly into your React projects.

Understanding Context and useContext

Before diving into using useContext in class component, let's briefly understand what React Context API and the useContext hook are.

React's Context API

The Context API is a feature in React that allows you to share data between components without having to pass it explicitly through props at every level of the component tree. It's especially useful for global state management, theme configuration, and localization.

Context is composed of two main parts:

  • Provider: A component that provides the context to its descendants.
  • Consumer: Components that consume the context data.

The useContext Hook

The useContext hook is part of React hooks API, introduced in React 16.8. It allows functional components to access the context provided by a Context.Provider component. useContext simplifies working with context by providing a straightforward way to access its values without using a Consumer component.

Prerequisites

Before we proceed, ensure you have the following prerequisites in place:

  • Node.js and npm (Node Package Manager) installed on your machine.
  • A basic understanding of React.js and JavaScript.

Setting Up a React Project

Let's begin by creating a new React project. Open your terminal and run the following commands:

npx create-react-app class-context-example
cd class-context-example
npm start

This will create a new React project and start the development server.

Creating a Context Provider

To use useContext in class components, we first need to create a context and a context provider. Create a new file named ThemeContext.js in your project's src folder:

// src/ThemeContext.js
 import React, { Component, createContext } from 'react';
 // Create a context
const ThemeContext = createContext();
 class ThemeProvider extends Component {
  state = {
    theme: 'light',
  };
   toggleTheme = () => {
    this.setState((prevState) => ({
      theme: prevState.theme === 'light' ? 'dark' : 'light',
    }));
  };

  render() {
    return (
      <ThemeContext.Provider
        value={{
          theme: this.state.theme,
          toggleTheme: this.toggleTheme,
        }}
      >
        {this.props.children}
      </ThemeContext.Provider>
    );
  }
}

export { ThemeProvider, ThemeContext };

In this code:

  • We import Component and createContext from React to create a class-based context provider.
  • We define a ThemeProvider class that extends Component. This class manages the theme state and provides a toggleTheme method to toggle between light and dark themes.
  • Inside the render method of the ThemeProvider, we wrap its children components with ThemeContext.Provider. This provider exposes the theme and toggleTheme function through its value prop.

Using useContext in Class Components

Now that we have our ThemeProvider, let's explore how to use useContext in a class component. Create a new file named ClassComponent.js in the src folder:

// src/ClassComponent.js

import React from 'react';
 import { ThemeContext } from './ThemeContext';
 class ClassComponent extends React.Component {
   // Access the context using the static contextType
  static contextType = ThemeContext;
   render() {
    const { theme, toggleTheme } = this.context;
     return (
      <div className={`class-component ${theme}`}>
        <h2>Class Component</h2>
        <p>Current theme: {theme}</p>
        <button onClick={toggleTheme}>Toggle Theme</button>
      </div>
    );
  }
}

export default ClassComponent;

In this class component:

  • We import ThemeContext from the ThemeContext.js file.
  • We use the static contextType property to access the context. This property allows us to consume the context and access its values using this.context.
  • Inside the render method, we destructure the theme and toggleTheme values from the context and use them to display the current theme and toggle the theme when the button is clicked.

Benefits of Combining Class Components with useContext

Combining class components with useContext offers several benefits:

  • Seamless Integration: You can seamlessly integrate new class components into a project that primarily uses functional components and hooks.

  • Share Context Data: Class components can easily share context data and consume it without significant code changes.

  • Reuse Existing Components: If you have existing class components, you can use them in the context of your functional component-based application without the need to refactor them.

  • Transition Period: If you're in the process of transitioning from class components to functional components, using useContext in class components allows you to gradually migrate your codebase.

Practical Example: Theming a React App

Let's put our knowledge to use in a practical example by implementing a theme toggle feature in a React app using class components and useContext. This example will demonstrate how to switch between light and dark themes across different parts of your application.

Creating Theme-aware Components

First, let's create a functional component that can switch between light and dark themes. Create a new file named ThemeAwareComponent.js in the src folder:

// src/ThemeAwareComponent.js

import React, { useContext } from 'react';
 import { ThemeContext } from './ThemeContext';
 function ThemeAwareComponent() {
  const { theme, toggleTheme } = useContext(ThemeContext);
   return (
    <div className={`theme-aware-component ${theme}`}>
      <h2>Theme-Aware Component</h2>
      <p>Current theme: {theme}</p>
      <button onClick={toggleTheme}>Toggle Theme</button>
    </div>
  );
}

export default ThemeAwareComponent;

In this functional component, we use the useContext hook to access the theme context and toggle theme functionality. This component will respond to theme changes made from anywhere in the app.

Using Theme-aware Components

Now, let's update the App.js file to use both the ClassComponent and ThemeAwareComponent across our app:

// src/App.js

import React from 'react';
 import './App.css';
 import ClassComponent from './ClassComponent';
 import ThemeAwareComponent from './ThemeAwareComponent';
 import { ThemeProvider } from './ThemeContext';
 function App() {
  return (
    <div className="App">
      <h1>Using useContext in Class Components</h1>
      <ThemeProvider>
        <ClassComponent />
        <ThemeAwareComponent />
      </ThemeProvider>
    </div>
  );
}

export default App;

In the App component:

  • We import and use both the ClassComponent and ThemeAwareComponent.
  • We wrap these components with the ThemeProvider to provide the theme context to all child components, whether functional or class-based.

Best Practices and Considerations

When using useContext in class components, keep in mind the following best practices and considerations:

  • Static ContextType: Use the static contextType property to access context in class components. This property should be set to the context you want to consume.

  • Context Updates: Be aware that class components using useContext will not re-render automatically when context values change. To achieve reactivity, consider using lifecycle methods like componentDidUpdate to trigger updates manually when context values change.

  • Functional Components: Consider using functional components and hooks for new parts of your application whenever possible. Hooks like useState, useEffect, and useContext provide a more concise and modern way to manage component logic.

  • Refactoring: If you plan to migrate from class components to functional components gradually, consider refactoring class components that use useContext to functional components over time. This will help simplify your codebase.

Conclusion

In this guide, we explored how to use the useContext hook in class components, allowing you to leverage the benefits of both class-based and functional components in your React applications. We started by understanding the concepts of React's Context API and the useContext hook.

By creating a practical example of theming a React app, we demonstrated how class components can seamlessly consume context data and interact with functional components that use useContext. This approach offers flexibility and ease of integration when transitioning between class and functional components.

As you continue working with React, consider the specific needs of your project and team when deciding whether to use class components, functional components, or a combination of both. Understanding how to use useContext in class components provides you with a valuable tool for maintaining and evolving your React applications.

When it comes to hiring top-notch React.js developers, look no further than CronJ. CronJ is your reliable partner for all your React.js development needs. With a talented team of React.js experts, CronJ excels in delivering high-quality web and react software development services, UI/UX design, and consulting services.

References

  1. https://legacy.reactjs.org/
  2. Split function in React js
  3. Difference between stateless and stateful components in React
  4. Pagination example in React js
In case you have found a mistake in the text, please send a message to the author by selecting the mistake and pressing Ctrl-Enter.
Jeff Smith 1K
Hello! My name is Jeff Smith. I’m a web designer and front-end web developer with over twenty years of professional experience in the design industry.
Comments (0)

    No comments yet

You must be logged in to comment.

Sign In / Sign Up