← Back to React Course | Chapter 9: State Management | Lesson 1 of 10

Context API से State Management

State management के लिए Context API उपयोग करना घर-भर में एक intercom install करने जैसा है, बीच के हर hallway से room to room messages चिल्लाने के बजाय।
Syntax
markup
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 बनाता है।

Note: अगर आप एक जैसा prop तीन या ज़्यादा component layers से बिना बदले pass कर रहे हैं, तो यह Context की ओर जाने का एक strong signal है।
Warning: हर piece of state को Context की ज़रूरत नहीं होती — सिर्फ एक parent और इसके direct child द्वारा उपयोग होने वाले state के लिए, plain props ज़्यादा simple और fine हैं।

उदाहरण: The Problem: Prop Drilling

markup
<!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 करते हुए।

Note: createContext() और Provider आमतौर पर एक बार define किए जाते हैं, आपके app के top के पास, और जहां ज़रूरत हो वहां import किए जाते हैं।
Warning: useContext उपयोग करने वाला एक component matching Provider के INSIDE रेंडर होना चाहिए, नहीं तो इसे context की default value मिलती है।

उदाहरण: Solving It with Context

markup
<!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 के।

Note: ज़्यादा complex update logic वाले state के लिए, useState को इसी Provider pattern के अंदर useReducer से swap करें — Context वाला हिस्सा identical रहता है।
Warning: जैसे एक app बड़ा होता है, कई unrelated pieces of state रखने वाला एक single Context prop drilling जितना ही hard to manage बन सकता है — जब ऐसा हो तो focused contexts में split करें।

उदाहरण: Combining Context with useState for Full State Management

markup
<!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>
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. सारे app state के लिए एक giant Context उपयोग करना focused contexts (auth, theme, cart) में split करने के बजाय।
  2. यह भूल जाना कि हर consumer context value बदलने पर re-render होता है, भले ही वे इसका सिर्फ एक हिस्सा उपयोग करते हों।
  3. 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) से उपलब्ध है।

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.