4. Context API
What is Context API?
The Context API in React is a built-in feature that allows you to share data (like variables, functions, objects) across multiple components without having to pass props manually at every level.
Why is it needed?
In a normal React app, data is passed from parent to child through props. But when the component tree is deep, and many components need the same data, passing props through many layers becomes difficult. This is called prop drilling. Context API solves this problem by providing a global way to share data.
How it works – Step by Step
- Create a Context
This creates a context object that can be shared.
import { createContext } from 'react'
const MyContext = createContext()
- Provide the Context
You wrap your component tree with a Provider and pass the data you want to share using thevalueprop.
<MyContext.Provider value={sharedData}>
<ChildComponent />
</MyContext.Provider>
- Use the Context
In any child component, you can use theuseContexthook to access the data.
import { useContext } from 'react'
const data = useContext(MyContext)
Example
Suppose you want to share a user’s name across components.
UserContext.js
import { createContext } from 'react'
export const UserContext = createContext()
App.js
import { UserContext } from './UserContext'
import Profile from './Profile'
function App() {
const user = { name: "Sanskar" }
return (
<UserContext.Provider value={user}>
<Profile />
</UserContext.Provider>
)
}
Profile.js
import { useContext } from 'react'
import { UserContext } from './UserContext'
function Profile() {
const user = useContext(UserContext)
return <p>Hello, {user.name}</p>
}
How it helps
Without context, you would have to pass user through all intermediate components. With context, any component under the Provider can directly access the data using useContext.
When to use Context API
- When many components at different levels need access to the same data
- For global data like user authentication, theme, language, or cart items
When not to use
- For frequently changing data or performance-critical parts, prefer local state or libraries like Redux
Better file structure to store and use context for good practice
A modular, scalable, and maintainable approach to global state management using Context API, built with clear separation of concerns and reusable abstractions
UserContext.js

UserContextProvider.jsx

App.jsx

Client.jsx

1. UserContext.js
Purpose:
Only creates the context.
This file is responsible for exporting the context object, which other files can use to access shared data.
Why separate?
Keeps the context definition clean and reusable.
You might want to use the context in multiple files, and this keeps it in one place.
Code Summary:
const UserContext = createContext()
- This line creates the context object.
- No state or logic here.
2. UserContextProvider.jsx
Purpose:
Wraps your app with the context and provides data using a state.
Why separate?
Keeps state logic (like useState) and the context provider component separate from the plain context.
This makes it easy to manage and test.
What it does:
- Uses
useStateto define data (name,setname) - Wraps
UserContext.Provideraroundchildrento share data globally
Code Summary:
<UserContext.Provider value={{name, setname}}>
{children}
</UserContext.Provider>
- Makes
nameavailable to any component inside it.
3. App.jsx
Purpose:
Uses the UserContextProvider to wrap your app.
Why like this?
So that any component like <Client /> can directly access name without prop drilling.
Summary
| File | Responsibility | Reason for Separation |
|---|---|---|
UserContext.js |
Just creates and exports the context | Keeps definition clean |
UserContextProvider.jsx |
Manages state and provides context | Separates logic from definition |
App.jsx |
Wraps app with provider | Makes data globally available |