A component-scoped context is designed to be used within a specific component tree, providing a convenient way to manage state or pass data to nested components instead of using prop drilling. This approach helps keep components modular and the codebase cleaner.
A step-by-step guide to creating a component-scoped context
1. Create a context with a default value.
const ComponentContext = createContext<number>(0);
2. Create a custom hook to use the component context.
export function useComponentContext() {
const ctx = useContext(ComponentContext);
if (!ctx) {
throw new Error("useComponentContext must be used within a ComponentContext.Provider");
}
return ctx;
}
3. Create a parent component that receives an id
prop and provides it to its child components.
const ParentComponent = ({ id }: { id: number }) => {
return (
<ComponentContext.Provider value={id}>
<h2>Parent Component</h2>
<ChildComponent />
</ComponentContext.Provider>
);
};
export default ParentComponent;
4. Create a child component that retrieves the id
from the component context using useComponentContext()
import { useComponentContext } from "./ParentComponent";
const ChildComponent = () => {
const id = useComponentContext();
return (
<div>
<h3>Child Component</h3>
<div>{id}</div>
</div>
);
};
export default ChildComponent;
Full example
App.tsx
<ParentComponent id={2} />
<hr />
<ParentComponent id={4} />
<hr />
<ParentComponent id={6} />
ParentComponent.tsx
// Local Component Context
const ComponentContext = createContext<number>(0);
export function useComponentContext() {
const ctx = useContext(ComponentContext);
if (!ctx) {
throw new Error(
"useComponentContext must be used within a ComponentContext.Provider"
);
}
return ctx;
}
const ParentComponent = ({ id }: { id: number }) => {
return (
<ComponentContext.Provider value={id}>
<h2>Parent Component with id={id}</h2>
<ChildComponent1 />
</ComponentContext.Provider>
);
};
export default ParentComponent;
ChildComponent1.tsx
import ChildComponent2 from "./ChildComponent2";
import { useComponentContext } from "./ParentComponent";
const ChildComponent1 = () => {
const id = useComponentContext();
return (
<div>
<h3>Child Component 1</h3>
<div>{id}</div>
<ChildComponent2 />
</div>
);
};
export default ChildComponent1;
ChildComponent2.tsx
import { useComponentContext } from "./ParentComponent";
const ChildComponent2 = () => {
const id = useComponentContext();
return (
<div>
<h4>Child Component 2</h4>
<div>{id}</div>
</div>
);
};
export default ChildComponent2;
Output
Parent Component with id=2
Child Component 1
2
Child Component 2
2
Parent Component with id=4
Child Component 1
4
Child Component 2
4
Parent Component with id=6
Child Component 1
6
Child Component 2
6