DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 968,873 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
shirisha95
shirisha95

Posted on

Understanding React Context

If you think about it, the top-down data flow is what gave react superpowers.

  • You have more control over your data. No more early JS days where you sweep through heaps & loads of JS files and figure out what mutated your state.
  • It’s easier to debug, as you know what is coming from where

But what if we are building a deeply nested app?

const App = () => {
  return (
    <div>
      App Contents
      <Toolbar theme={store.theme} />
    </div>
  );
};

const Toolbar = ({ theme }) => {
  return (
    <div>
      <Button theme={theme} label="Button 1" />
      <Button theme={theme} label="Button 2" />
    </div>
  );
};

const Button = ({ theme, label }) => {
  return (
    <button style={{ backgroundColor: theme === "dark" ? "black" : "white" }}>
      {label}
    </button>
  );
};

Enter fullscreen mode Exit fullscreen mode

This is called prop-drilling, and this gets even worse if you have more layers of components between the data source and user. How to solve this? React Context to the rescue!!

Solving prop drilling by using the Context API

The Context API lets you broadcast your state/data to multiple components by wrapping them with a context provider. Pass your state as value attribute to the contextProvider, the children components can then tap into this provider using a context consumer or the useContext Hook.

Step 1: Create Context

// ThemeContext.jsx
import React from "react";
const ThemeContext = React.createContext();
export default ThemeContext;
Enter fullscreen mode Exit fullscreen mode

Step 2: Context Provider:
Now we can wrap all the context users with the Context Provider, and pass the value that we want to 'broadcast'.

const App = () => {
  return (
    <ThemeContext.Provider value={{ theme: store.theme }}>
      App Contents
      <Toolbar />
    </ThemeContext.Provider>
  );
};
Enter fullscreen mode Exit fullscreen mode

Now, how do we access the theme from its descendants Toolbar, Button?

Step 3: Context Consumer: useContext
To access the context, we use useContext hook from any descendant of Component App.

import React from "react";
import { ThemeContext } from "./ThemeContext";

const Button = ({ theme, label }) => {
  const { theme } = React.useContext(ThemeContext);
  return (
    <button style={{ backgroundColor: theme === "dark" ? "black" : "white" }}>
      {label}
    </button>
  );
};
Enter fullscreen mode Exit fullscreen mode

Here, Our rendered output remains the same, but the code underneath is a bit leaner and cleaner.

That's all! I hope that I helped clarify why you need context and how to implement it. Feel free to post any questions, comments or any suggestions.

Top comments (0)

🀯

"I made 10x faster JSON.stringify() functions, even type safe"

☝️ Must read for JS devs