Context API से State Management
In this page:
const NameContext = createContext();
function NameProvider({ children }) {
const [state, setState] = useState(initial);
return (
<NameContext.Provider value={{ state, setState }}>
{children}
</NameContext.Provider>
);
}
const { state, setState } = useContext(NameContext);
समस्या: Prop Drilling
बिना shared state management के, एक data को top-level component से एक deeply nested component तक पहुंचाने का मतलब है उसे बीच के हर component से एक prop के रूप में pass करना, उन components से भी जो खुद उसे उपयोग नहीं करते।
इसे 'prop drilling' कहा जाता है, और यह refactoring को painful बनाता है।
उदाहरण: The Problem: Prop Drilling
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
function GrandChild({ user }) { return <p>Hello, {user}</p>; }
function Child({ user }) { return <GrandChild user={user} />; }
function App() {
const user = "Asha";
return <Child user={user} />;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
</script>
</body>
</html>
Context से इसे Solve करना
Context एक top-level Provider को किसी भी descendant को एक value available कराने देता है, चाहे वह कितना भी deeply nested हो, उसे हर layer में prop के रूप में pass किए बिना।
जिस भी component को वह value चाहिए वह सीधे useContext call करता है, बीच के components को पूरी तरह skip करते हुए।
उदाहरण: Solving It with Context
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
const UserContext = React.createContext("Guest");
function GrandChild() {
const user = React.useContext(UserContext);
return <p>Hello, {user}</p>;
}
function Child() { return <GrandChild />; }
function App() {
return <UserContext.Provider value="Asha"><Child /></UserContext.Provider>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
</script>
</body>
</html>
Full State Management के लिए Context को useState के साथ Combine करना
Context को useState के साथ pair करना इसे एक lightweight लेकिन complete state-management solution बना देता है: Provider component state और setter रखता है, और कोई भी descendant current value पढ़ और update दोनों कर सकता है, बिना किसी external library के।
उदाहरण: Combining Context with useState for Full State Management
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
const CountContext = React.createContext();
function CountProvider({ children }) {
const [count, setCount] = React.useState(0);
return <CountContext.Provider value={{ count, setCount }}>{children}</CountContext.Provider>;
}
function Counter() {
const { count, setCount } = React.useContext(CountContext);
return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}
function App() {
return <CountProvider><Counter /></CountProvider>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
</script>
</body>
</html>
- सारे app state के लिए एक giant Context उपयोग करना focused contexts (auth, theme, cart) में split करने के बजाय।
- यह भूल जाना कि हर consumer context value बदलने पर re-render होता है, भले ही वे इसका सिर्फ एक हिस्सा उपयोग करते हों।
- Provider की value memoize न करना, जो हर parent render पर unnecessary re-renders का कारण बनता है।
- Context API state management createContext + useState + एक Provider उपयोग करके app-wide state share करता है।
- यह 'prop drilling' से बचता है — state को कई component layers से manually pass करना जिन्हें खुद इसकी ज़रूरत नहीं।
- Simple to medium apps के लिए, Context + useReducer/useState अक्सर एक अलग library जैसे Redux के बिना काफी है।
- State को कई focused contexts में split करना limit करता है कि किसी भी change पर कितने components re-render होते हैं।
React 16.3 (stable Context API) से उपलब्ध है।
Chapter Quiz — Complete all 10 topics to unlock
0/10 topics done
Complete these topics first: