context का उपयोग करके प्रॉप drilling के बिना डेटा को इधर-उधर पहुँचाएं, और साथ ही इसके re-renders तथा सीमाओं को नियंत्रण में रखें।
इस पाठ को Kodokon में खोलेंProp drilling उन props को कहते हैं जो तीन या चार मध्यवर्ती कंपोनेंट से होकर गुज़रते हैं बिना वहाँ उपयोग हुए, सिर्फ़ पेड़ के किसी पत्ते तक पहुँचने के लिए। वे जिस भी परत को पार करते हैं वह ऐसे डेटा से जुड़ जाती है जिसकी उसे परवाह नहीं है। Context इस परिवहन समस्या को हल करता है: createContext चैनल बनाता है, एक provider एक मान प्रकाशित करता है, और useContext इसे किसी भी descendant से पढ़ता है। यह बारीकी याद रखें: context state को परिवहन करता है, इसे प्रबंधित नहीं करता - मान अब भी एक कंपोनेंट में रहता है, यहाँ provider में।
import { createContext, useMemo, useState } from "react";
const ThemeContext = createContext(null);
function ThemeProvider({ children }) {
const [theme, setTheme] = useState("dark");
const value = useMemo(
() => ({ theme, setTheme }),
[theme]
);
return (
<ThemeContext.Provider value={value}>
{children}
</ThemeContext.Provider>
);
}जब provider का मान बदलता है, तो सभी consumers फिर से render होते हैं, यहाँ तक कि गहराई में nested वाले भी - और React.memo उनकी रक्षा नहीं करता, क्योंकि यह props की तुलना करता है, context की नहीं। क्लासिक जाल स्थिति को और बिगाड़ देता है: value={{ theme, setTheme }} लिखना provider के हर render पर एक नई object बनाता है, इसलिए एक नया reference, इसलिए झरने की तरह re-renders होते हैं भले ही theme नहीं बदला हो। ऊपर वाला useMemo इसी के लिए है। सेटअप को एक access hook से पूरा करें जो provider के बाहर स्पष्ट रूप से विफल हो।
import { useContext } from "react";
function useTheme() {
const context = useContext(ThemeContext);
if (context === null) {
throw new Error(
"useTheme must be inside <ThemeProvider>"
);
}
return context;
}एक context बनाने से पहले, पहले composition विकल्प को पूरी तरह आज़मा लें। यदि कोई मध्यवर्ती परत केवल एक prop को आगे पहुँचाने के अलावा कुछ नहीं करती, तो संरचना उलट दें: पेड़ के शीर्ष पर, जहाँ डेटा रहता है, element बनाएं, और उसे children या एक समर्पित prop के ज़रिए नीचे पास करें। मध्यवर्ती परत generic बन जाती है और डेटा अब किसी ऐसे कंपोनेंट से नहीं गुज़रता जो उसका उपयोग नहीं करता।
function App({ currentUser }) {
return (
<Layout
header={<TopBar user={currentUser} />}
content={<Dashboard />}
/>
);
}