Diego Betto's Blog
React and useContext

September 27, 2023 · 4 min di lettura

React: how useContext works (with examples)

How the useContext hook works in React to share data between components without props drilling, with a practical step-by-step example.

Condividi:XLinkedInFacebookWhatsApp

In React, the useContext hook lets you share data between components, even when they aren’t directly connected. This is a simpler and more flexible way to share data compared to the props drilling approach.

Introduction

The useContext hook is a powerful tool that can be used to share data between components in a simple, efficient, and maintainable way.

How it works

The useContext hook accepts two parameters:

  • the context, which is an object representing the data you want to share;
  • a selector, which is a function used to get the context’s value.

The context is created using the createContext() function.

const ThemeContext = createContext(null);

The selector is a function used to get the context’s value. The selector can be a simple function that returns the context’s value, or it can be a function that processes the context’s value.

To use the useContext hook, you need to import it from the React.js package.

import React, { useContext } from "react";

Then, you need to use the useContext hook inside the components that need to access the context’s data.

const App = () => {
  const theme = useContext(ThemeContext);

  return (
    <div>
      <h1>The current theme is {theme}</h1>
    </div>
  );
};

Example

Here’s an example of using the useContext hook to share a theme between components.

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

const ThemeContext = createContext();

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

  const toggleTheme = () => {
    setTheme(theme === "light" ? "dark" : "light");
  };

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

const App = () => {
  return (
    <ThemeProvider>
      <Content />
    </ThemeProvider>
  );
};

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

  return (
    <div>
      <h1>The current theme is {theme}</h1>
      <Button theme={theme} onClick={toggleTheme}>
        Change theme
      </Button>
    </div>
  );
};

const Button = ({ theme, onClick }) => {
  return (
    <button onClick={onClick} style={{ backgroundColor: theme === "dark" ? "#000" : "#fff" }}>
      {theme}
    </button>
  );
};

export default App;

In this example, the context is represented by the ThemeContext object. The context is created using the createContext() function.

The ThemeProvider component is used to provide the context to child components. The ThemeProvider component accepts children as a parameter, which is a component that will be rendered inside the context.

const ThemeContext = createContext();

createContext is used to initialize a new React Context. This context can then be used to pass data to various React components without needing to use props.

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

  // rest of the code
};

Let’s define a Provider component for our context. This provider will use the React Hook useState to create a state that tracks the current theme. The provider will then be used to make this state available to all components that need to access the theme.

const App = () => {
  return (
    <ThemeProvider>
      <Content />
    </ThemeProvider>
  );
};

Let’s wrap our entire application content inside ThemeProvider. This lets us access the theme state in all child components.

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

  // rest of the code
};

We use the React Hook useContext to access the theme state and the function to change it.

const Button = ({ theme, onClick }) => {
  // rest of the code
};

This is a simple Button component that receives the current theme and an onClick function as props. The button’s background color changes depending on the theme. Note: If you think you’ll be using the theme in many different places in your code, it can be useful to make the theme context available through a custom Hook. This can simplify access to the theme context.

Advantages

Using the useContext hook offers several advantages over the props drilling approach.

  • It’s simpler and more flexible. You don’t need to pass data from one component to another, you just need to use the useContext() hook to get the context’s value.
  • It’s more efficient. The useContext() hook runs only once, when the component mounts.
  • It’s more maintainable. The code is easier to understand and maintain, since you don’t need to keep track of the props chain.

Conclusion

The useContext hook is a powerful tool that can be used to share data between components in a simple, efficient, and maintainable way.

If you’re interested in seeing useContext combined with useState in a practical case, I’ve also written a dedicated example on useContext with useState. If your state is more complex instead, take a look at the guide to useReducer.

Condividi:XLinkedInFacebookWhatsApp