Skip to content
React Conext기술 정리

A close look at React Context

2 min readTech notesMoved from my Tistory blogRead the Korean original

The reason I want to take a close look at React Context today is that, as far as I can tell, many companies using React make active use of Context in situations where props need to be passed down.

Here I'll go over the concept of Context and how to use it, based on the official docs (React v18.3.1).

https://ko.react.dev/learn/passing-data-deeply-with-context

Passing Data Deeply with Context (React)

Why did React Context come about?

If you've used React, you have probably passed props from a parent component to a child component.

Passing props directly between a parent and a child isn't a big problem, but if you have to keep passing props through several child components in between, the process gets more and more tedious.

Especially if you use TypeScript, you have to declare the props types in each child component every time, which can make it even more annoying.

To solve this, React introduced Context, which lets you provide a value to the component you want, as if "teleporting" it, instead of passing props one by one.

Prop drilling

Source: React official docs
Figure 1. Source: React official docs

If you open the codesandbox link, each <Heading> component is currently being passed a level prop, and we want to change the code as follows.

Image of passing a level prop to each <Heading> component
Figure 2. Image of passing a level prop to each <Heading> component
jsx
import Heading from './Heading.js';
import Section from './Section.js';

export default function Page() {
  return (
    <Section level={1}>
      <Heading>Title</Heading>
      <Section level={2}>
        <Heading>Heading</Heading>
        <Heading>Heading</Heading>
        <Heading>Heading</Heading>
        <Section level={3}>
          <Heading>Sub-heading</Heading>
          <Heading>Sub-heading</Heading>
          <Heading>Sub-heading</Heading>
          <Section level={4}>
            <Heading>Sub-sub-heading</Heading>
            <Heading>Sub-sub-heading</Heading>
            <Heading>Sub-sub-heading</Heading>
          </Section>
        </Section>
      </Section>
    </Section>
  );
}

Step 1: Create the context

First, you need to create a context. So that components can use it, you need to export it from a file.

js
import { createContext } from 'react';

export const LevelContext = createContext(1);

Step 2: Use the context

Import the useContext Hook from React and the context you created.

Remove the level prop and read the value from LevelContext, the context imported above, instead.

js
import { useContext } from 'react';
import { LevelContext } from './LevelContext.js';

export default function Heading({ children }) {
  const level = useContext(LevelContext);
  // ...
}

Step 3: Provide the context

To provide LevelContext to the children, wrap them in a context provider.

jsx
import { LevelContext } from './LevelContext.js';

export default function Section({ level, children }) {
  return (
    <section className="section">
      <LevelContext.Provider value={level}>
        {children}
      </LevelContext.Provider>
    </section>
  );
}

Going over it once more, these are the steps we took.

  1. Create a context named LevelContext with the createContext hook, setting its default value to 1.
  2. In the Section component, wrap the child components in LevelContext.Provider and pass the level value to value.
  3. In the Heading component, remove the level that used to come in through props, and instead get the level value with the useContext(LevelContext) hook and do the branching it needs.

Here is the implementation.

https://codesandbox.io/p/sandbox/hl9ysq

https://codesandbox.io/p/sandbox/hl9ysq

My thoughts

Today I looked at React's Context, which lets you "teleport" props. My personal convention is to pass props directly as long as the component depth doesn't go beyond 3 levels, and when it goes past 3 levels, I've mostly solved it with a global state management library such as Redux Toolkit or Zustand.

At my company we use Context very rarely right now, but I think it's important to follow each company's conventions at other companies too. If the existing code passes props through Context, following that approach is the right call, and if it uses a global state management library, I think you should go along with that. So I feel it's important to adapt to the situation, and I'm studying various approaches, including Context, so that I can adapt easily to any environment.

  • #Context API
  • #React
  • #Daily Blogging Challenge
  • #Tistory Challenge

More in Tech notes