Today’s TIL is on React’s use of Context. Please note, all the code I have provided below, unless explicitly stated otherwise, is from React.dev docs.
Context: why?
- Lets a parent component provide data to the entire tree below it, without having to prop drill.
- Prop drill: When you’re passing down the prop to multiple levels of children
Use case
Maybe you have a
// App.jsx
<Section>
<Heading level={3}>About</Heading>
<Heading level={3}>Photos</Heading>
<Heading level={3}>Videos</Heading>
</Section>
This is kind of cumbersome - can we somehow pass {3} to the Section and have the Heading components access it without receiving it as a prop? Answer: CONTEXT!
Syntax for creating context:
// LevelContext.jsx
import { createContext } from 'react';
export const LevelContext = createContext(1); // 1 is the default value
You usually create the context as a separate module/file. Then, if you want to utilize this specific context in your JSX files:
// Heading.jsx
import { useContext } from 'react';
import { LevelContext } from './LevelContext.js';
With these two import statements, you import the useContext hook from react, and also import the context you want to utilize.
For the component that needs to receive this data, you utilize the useContext hook:
// Heading.jsx
import { useContext } from 'react';
import { LevelContext } from './LevelContext.js';
export const Heading = () => {
const level = useContext(LevelContext);
//
}
Since the Heading doesn’t directly receive the level prop, you now set that value on
import { LevelContext } from './LevelContext.js';
export default function Section({ level, children }) {
return (
<section className="section">
<LevelContext.Provider value={level}>
{children}
</LevelContext.Provider>
</section>
);
}
Note, you use a method of LevelContext, Provider()
and set a value of the heading level you’d like. Also, LevelContext.Provider() doesn’t necessarily have to be in the immediate parent component (Section.jsx) in this case, depending on what you’re trying to achieve.
Caution: Don’t overuse context
React.dev’s recommendation prior to using Context:
- Pass the information as props
- Extract components and pass JSX as children to them.
More on the second method:
- For example, let’s say you have
<App />
-><Layout />
-> and<Post/>
components and want to passpostList
state from App to Post. You will have to passpostList
from App to Layout, and then Post. Technically, since theLayout
component doesn’t need the postList prop, instead of writing<Layout postList={postList} />
, you can have Layout take children as a prop, and write<Layout><Posts postList={postList} /></Layout>.