Introduction

The Context API is a powerful feature in React that allows you to share state across the entire application (or part of it) without having to pass props down manually at every level. This is particularly useful for global data such as user authentication, theme settings, or language preferences.

Key Concepts

  1. Context Creation: Creating a context using React.createContext().
  2. Provider: A component that provides the context value to its children.
  3. Consumer: A component that consumes the context value.
  4. useContext Hook: A hook that allows functional components to consume context values.

Creating a Context

To create a context, you use the React.createContext() function. This function returns an object with two properties: Provider and Consumer.

import React from 'react';

// Create a Context
const MyContext = React.createContext();

Providing Context

The Provider component is used to wrap the part of your application where you want the context to be available. It accepts a value prop, which will be passed to all consuming components.

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

const MyContext = React.createContext();

const MyProvider = ({ children }) => {
  const value = { user: 'John Doe' };

  return (
    <MyContext.Provider value={value}>
      {children}
    </MyContext.Provider>
  );
};

ReactDOM.render(
  <MyProvider>
    <App />
  </MyProvider>,
  document.getElementById('root')
);

Consuming Context

There are two main ways to consume context: using the Consumer component or the useContext hook.

Using the Consumer Component

The Consumer component uses the render prop pattern to access the context value.

import React from 'react';
import { MyContext } from './MyProvider';

const MyComponent = () => (
  <MyContext.Consumer>
    {value => <div>User: {value.user}</div>}
  </MyContext.Consumer>
);

export default MyComponent;

Using the useContext Hook

The useContext hook is a more modern and concise way to consume context in functional components.

import React, { useContext } from 'react';
import { MyContext } from './MyProvider';

const MyComponent = () => {
  const context = useContext(MyContext);

  return <div>User: {context.user}</div>;
};

export default MyComponent;

Practical Example

Let's create a simple example where we manage a theme (light or dark) using the Context API.

Step 1: Create the Context

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

const ThemeContext = createContext();

const ThemeProvider = ({ children }) => {
  const [theme, setTheme] = useState('light');

  const toggleTheme = () => {
    setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light'));
  };

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
};

export { ThemeContext, ThemeProvider };

Step 2: Provide the Context

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { ThemeProvider } from './ThemeContext';

ReactDOM.render(
  <ThemeProvider>
    <App />
  </ThemeProvider>,
  document.getElementById('root')
);

Step 3: Consume the Context

import React, { useContext } from 'react';
import { ThemeContext } from './ThemeContext';

const ThemedComponent = () => {
  const { theme, toggleTheme } = useContext(ThemeContext);

  return (
    <div style={{ background: theme === 'light' ? '#fff' : '#333', color: theme === 'light' ? '#000' : '#fff' }}>
      <p>The current theme is {theme}</p>
      <button onClick={toggleTheme}>Toggle Theme</button>
    </div>
  );
};

export default ThemedComponent;

Exercise

Task

  1. Create a context to manage user authentication status.
  2. Provide the context to your application.
  3. Consume the context in a component to display the user's authentication status and a button to toggle the status.

Solution

Step 1: Create the Context

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

const AuthContext = createContext();

const AuthProvider = ({ children }) => {
  const [isAuthenticated, setIsAuthenticated] = useState(false);

  const toggleAuth = () => {
    setIsAuthenticated((prevAuth) => !prevAuth);
  };

  return (
    <AuthContext.Provider value={{ isAuthenticated, toggleAuth }}>
      {children}
    </AuthContext.Provider>
  );
};

export { AuthContext, AuthProvider };

Step 2: Provide the Context

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { AuthProvider } from './AuthContext';

ReactDOM.render(
  <AuthProvider>
    <App />
  </AuthProvider>,
  document.getElementById('root')
);

Step 3: Consume the Context

import React, { useContext } from 'react';
import { AuthContext } from './AuthContext';

const AuthStatus = () => {
  const { isAuthenticated, toggleAuth } = useContext(AuthContext);

  return (
    <div>
      <p>User is {isAuthenticated ? 'Authenticated' : 'Not Authenticated'}</p>
      <button onClick={toggleAuth}>Toggle Authentication</button>
    </div>
  );
};

export default AuthStatus;

Conclusion

In this section, we learned about the Context API in React, which allows for efficient state management across different parts of an application. We covered how to create, provide, and consume context using both the Consumer component and the useContext hook. We also implemented a practical example to manage themes and an exercise to manage user authentication status. Understanding the Context API is crucial for managing global state in a React application, and it serves as a foundation for more advanced state management solutions like Redux.

React Course

Module 1: Introduction to React

Module 2: React Components

Module 3: Working with Events

Module 4: Advanced Component Concepts

Module 5: React Hooks

Module 6: Routing in React

Module 7: State Management

Module 8: Performance Optimization

Module 9: Testing in React

Module 10: Advanced Topics

Module 11: Project: Building a Complete Application

© Copyright 2024. All rights reserved