← Back to React Course | Chapter 6: Custom Hooks & Advanced Patterns | Lesson 10 of 10

Context Provider Pattern का उपयोग

Context provider pattern एक family radio channel जैसा है — जो भी इसे tune में है वह announcement सुन सकता है बिना किसी को हर person को individually बताने के लिए दौड़ना पड़े।
Syntax
markup
const NameContext = createContext(defaultValue);

function NameProvider({ children }) {
  const [value, setValue] = useState(initial);
  return (
    <NameContext.Provider value={{ value, setValue }}>
      {children}
    </NameContext.Provider>
  );
}

const useName = () => useContext(NameContext);

Context बनाना और Provide करना

React.createContext() एक default value के साथ एक Context object बनाता है। Component tree के एक हिस्से को <MyContext.Provider value={...}> में wrap करना उस value को tree के अंदर nested हर component के लिए available बनाता है, चाहे यह कितना भी deep हो, props के through manually thread किए बिना।

Note: Context को एक sensible default value दें (दूसरा argument ज़रूरी नहीं, लेकिन createContext() एक accept भी करता है) ताकि एक provider के बाहर उपयोग किए गए components unexpectedly crash न हों।
Warning: सिर्फ Provider के INSIDE render किए गए components इसकी value पढ़ सकते हैं — Provider के JSX tree के बाहर एक component context के default value पर fall back करता है।

उदाहरण: Creating and Providing 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 ThemeContext = React.createContext("light");
function Display() {
  const theme = React.useContext(ThemeContext);
  return <p>Current theme: {theme}</p>;
}
function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Display />
    </ThemeContext.Provider>
  );
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  </script>
</body>
</html>

Provider + State को साथ Wrap करना

एक common pattern एक dedicated Provider component बनाना है जो खुद state रखता है और इसे (plus एक setter) context के through नीचे pass करता है, app में useState calls को बिखेरने के बजाय।

यह सभी related state और update logic को एक जगह रखता है।

Note: इस component को कुछ ऐसा नाम दें जैसे ThemeProvider, और इसे और raw ThemeContext (या एक custom hook) दोनों को एक ही file से export करें।
Warning: अगर ThemeProvider खुद app के top के पास render नहीं किया गया, तो सिर्फ tree में इसके नीचे वाले components shared state देखेंगे।

उदाहरण: Wrapping Provider + State Together

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 ThemeContext = React.createContext();
function ThemeProvider({ children }) {
  const [theme, setTheme] = React.useState("light");
  return <ThemeContext.Provider value={{ theme, setTheme }}>{children}</ThemeContext.Provider>;
}
function ThemeToggle() {
  const { theme, setTheme } = React.useContext(ThemeContext);
  return <button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>Theme: {theme}</button>;
}
function App() {
  return <ThemeProvider><ThemeToggle /></ThemeProvider>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  </script>
</body>
</html>

useContext को एक Custom Hook में Wrap करना

हर consumer को सीधे useContext(ThemeContext) call करने के बजाय, एक छोटा custom hook जैसे useTheme() expose करना common है जो यह internally करता है और provider के बाहर उपयोग होने पर एक helpful error भी throw कर सकता है।

यह misuse को जल्दी पकड़ना आसान बनाता है।

Note: Custom hook के अंदर एक clear error throw करना ('useTheme must be used within a ThemeProvider') एक silent undefined value की तुलना में बहुत debugging time बचाता है।
Warning: इस guard के बिना, provider भूल जाना एक component के अंदर deep एक confusing 'Cannot read properties of undefined' error produce करता है, एक clear message के बजाय।

उदाहरण: Wrapping useContext in a Custom Hook

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 ThemeContext = React.createContext(null);
function ThemeProvider({ children }) {
  const [theme, setTheme] = React.useState("light");
  return <ThemeContext.Provider value={{ theme, setTheme }}>{children}</ThemeContext.Provider>;
}
function useTheme() {
  const ctx = React.useContext(ThemeContext);
  if (!ctx) throw new Error("useTheme must be used within a ThemeProvider");
  return ctx;
}
function ThemeLabel() {
  return <p>Theme is: {useTheme().theme}</p>;
}
function App() {
  return <ThemeProvider><ThemeLabel /></ThemeProvider>;
}
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. हर render पर एक brand-new object literal को Context value के रूप में pass करना, जो हर consumer को re-render करता है भले ही असली data न बदला हो।
  2. Tree के उस हिस्से को Provider में wrap करना भूल जाना जिसे context की ज़रूरत है, इसलिए useContext default (अक्सर undefined) value return करता है।
  3. सब कुछ एक giant global context में डालना concerns को focused, अलग contexts में split करने के बजाय।
चैप्टर सारांश
  • Provider pattern component tree के एक हिस्से को Context.Provider में wrap करता है ताकि इसके सभी descendants के लिए एक value available हो।
  • Consumers value को useContext से पढ़ते हैं, इसे हर level पर props के through manually pass किए बिना।
  • Provider की value को useMemo में wrap करना हर render पर एक नया object बनाने से बचता है, unnecessary consumer re-renders रोकते हुए।
  • एक provider को एक custom hook (जैसे useTheme()) के साथ pair करना common है जो एक cleaner consumer API के लिए useContext को wrap करता है।
ब्राउज़र सपोर्ट

React 16.3 (stable Context API) से available है।

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.