useContext
useContext என்பது உங்கள் component-இலிருந்து context-ஐ read செய்து subscribe செய்ய உதவும் React Hook ஆகும்.
const value = useContext(SomeContext)மேற்கோள்
useContext(SomeContext)
உங்கள் component-ன் top level-இல் useContext-ஐ call செய்து context-ஐ read செய்து subscribe செய்யுங்கள்.
import { useContext } from 'react';
function MyComponent() {
const theme = useContext(ThemeContext);
// ...மேலும் examples-ஐ கீழே பார்க்கவும்.
அளவுருக்கள்
SomeContext: நீங்கள் முன்புcreateContextமூலம் create செய்த context. Context தானாக information-ஐ வைத்திருக்காது; components-இலிருந்து provide செய்யவோ read செய்யவோ முடியும் information வகையை மட்டும் அது குறிக்கிறது.
திரும்பும் மதிப்பு
useContext call செய்கிற component-க்கு context value-ஐ return செய்கிறது. Tree-இல் call செய்கிற component-க்கு மேல் இருக்கும் closest SomeContext-க்கு pass செய்யப்பட்ட value இதை தீர்மானிக்கிறது. அப்படிப்பட்ட provider எதுவும் இல்லையெனில், அந்த context-க்காக createContext-க்கு நீங்கள் pass செய்த defaultValue return செய்யப்படும். Return செய்யப்படும் value எப்போதும் up-to-date ஆக இருக்கும். ஏதேனும் context மாறினால், அதை read செய்யும் components-ஐ React automatic ஆக re-render செய்கிறது.
கவனிக்க வேண்டியவை
- ஒரு component-இல் உள்ள
useContext()call, அதே component return செய்யும் providers-ஆல் பாதிக்கப்படாது. பொருந்தும்<Context>,useContext()call செய்யும் component-க்கு மேலே இருக்க வேண்டும். - வேறுபட்ட
valueபெறும் provider-இலிருந்து தொடங்கி, குறிப்பிட்ட context-ஐ use செய்யும் எல்லா children-ஐயும் React automatically re-render செய்கிறது. முந்தைய மற்றும் அடுத்த valuesObject.iscomparison மூலம் ஒப்பிடப்படுகின்றன.memoமூலம் re-renders-ஐ skip செய்தாலும், children புதிய context values-ஐ பெறுவதை அது தடுக்காது. - உங்கள் build system output-இல் duplicate modules-ஐ உருவாக்கினால் (symlinks காரணமாக இது நடக்கலாம்), context உடையக்கூடும். Context வழியாக ஏதாவது pass செய்வது, context provide செய்ய நீங்கள் use செய்யும்
SomeContextமற்றும் அதை read செய்ய நீங்கள் use செய்யும்SomeContextஆகியவை===comparison-ல் தீர்மானிக்கப்படும் படி முழுமையாக அதே object ஆக இருந்தால் மட்டுமே வேலை செய்யும்.
பயன்பாடு
Tree-க்குள் ஆழமாக data pass செய்தல்
உங்கள் component-ன் top level-இல் useContext-ஐ call செய்து context-ஐ read செய்து subscribe செய்யுங்கள்.
import { useContext } from 'react';
function Button() {
const theme = useContext(ThemeContext);
// ...நீங்கள் pass செய்த context-க்கான context value-ஐ useContext return செய்கிறது. Context value-ஐ தீர்மானிக்க, React component tree-ஐ தேடி, அந்த குறிப்பிட்ட context-க்கான மேலே உள்ள closest context provider-ஐ கண்டுபிடிக்கிறது.
ஒரு Button-க்கு context pass செய்ய, அதையோ அதன் parent components-இல் ஒன்றையோ பொருந்தும் context provider-க்குள் wrap செய்யுங்கள்:
function MyPage() {
return (
<ThemeContext value="dark">
<Form />
</ThemeContext>
);
}
function Form() {
// ... renders buttons inside ...
}Provider மற்றும் Button இடையில் எத்தனை component layers இருந்தாலும் பரவாயில்லை. Form-க்கு உள்ளே எங்கிருந்தாலும் ஒரு Button useContext(ThemeContext) call செய்தால், அது value ஆக "dark"-ஐ பெறும்.
import { createContext, useContext } from 'react'; const ThemeContext = createContext(null); export default function MyApp() { return ( <ThemeContext value="dark"> <Form /> </ThemeContext> ) } function Form() { return ( <Panel title="வரவேற்பு"> <Button>பதிவு செய்</Button> <Button>உள்நுழை</Button> </Panel> ); } function Panel({ title, children }) { const theme = useContext(ThemeContext); const className = 'panel-' + theme; return ( <section className={className}> <h1>{title}</h1> {children} </section> ) } function Button({ children }) { const theme = useContext(ThemeContext); const className = 'button-' + theme; return ( <button className={className}> {children} </button> ); }
Context வழியாக pass செய்யப்பட்ட data-வை update செய்தல்
பல நேரங்களில், context காலப்போக்கில் மாற வேண்டும் என்று நீங்கள் விரும்புவீர்கள். Context-ஐ update செய்ய, அதை state-உடன் combine செய்யுங்கள். Parent component-இல் state variable-ஐ declare செய்து, current state-ஐ context value ஆக provider-க்கு கீழே pass செய்யுங்கள்.
function MyPage() {
const [theme, setTheme] = useState('dark');
return (
<ThemeContext value={theme}>
<Form />
<Button onClick={() => {
setTheme('light');
}}>
Light theme-க்கு மாற்று
</Button>
</ThemeContext>
);
}இப்போது provider-க்கு உள்ளே உள்ள எந்த Button-உம் current theme value-ஐ பெறும். Provider-க்கு pass செய்யும் theme value-ஐ update செய்ய setTheme call செய்தால், எல்லா Button components-உம் புதிய 'light' value உடன் re-render ஆகும்.
Example 1 of 5: Context வழியாக ஒரு value-ஐ update செய்தல்
இந்த example-இல், MyApp component ஒரு state variable-ஐ வைத்திருக்கிறது; பின்னர் அது ThemeContext provider-க்கு pass செய்யப்படுகிறது. “Dark mode” checkbox-ஐ check செய்தால் state update ஆகும். Provide செய்யப்பட்ட value மாறும்போது, அந்த context-ஐ use செய்யும் எல்லா components-உம் re-render ஆகும்.
import { createContext, useContext, useState } from 'react'; const ThemeContext = createContext(null); export default function MyApp() { const [theme, setTheme] = useState('light'); return ( <ThemeContext value={theme}> <Form /> <label> <input type="checkbox" checked={theme === 'dark'} onChange={(e) => { setTheme(e.target.checked ? 'dark' : 'light') }} /> Dark mode பயன்படுத்து </label> </ThemeContext> ) } function Form({ children }) { return ( <Panel title="வரவேற்பு"> <Button>பதிவு செய்</Button> <Button>உள்நுழை</Button> </Panel> ); } function Panel({ title, children }) { const theme = useContext(ThemeContext); const className = 'panel-' + theme; return ( <section className={className}> <h1>{title}</h1> {children} </section> ) } function Button({ children }) { const theme = useContext(ThemeContext); const className = 'button-' + theme; return ( <button className={className}> {children} </button> ); }
value="dark" "dark" string-ஐ pass செய்கிறது, ஆனால் value={theme} JSX curly braces மூலம் JavaScript theme variable-ன் value-ஐ pass செய்கிறது என்பதை கவனிக்கவும். Curly braces, strings அல்லாத context values-ஐயும் pass செய்ய அனுமதிக்கின்றன.
Fallback default value-ஐ குறிப்பிடுதல்
Parent tree-இல் அந்த குறிப்பிட்ட context-க்கான providers எதையும் React கண்டுபிடிக்க முடியாவிட்டால், useContext() return செய்யும் context value, நீங்கள் அந்த context-ஐ create செய்தபோது குறிப்பிட்ட default value-க்கு சமமாக இருக்கும்:
const ThemeContext = createContext(null);Default value ஒருபோதும் மாறாது. Context-ஐ update செய்ய வேண்டும் என்றால், மேலே விவரித்தபடி அதை state உடன் use செய்யுங்கள்.
பல நேரங்களில், null-க்கு பதிலாக default ஆக use செய்ய இன்னும் meaningful ஆன value இருக்கலாம், உதாரணமாக:
const ThemeContext = createContext('light');இவ்வாறு செய்தால், பொருந்தும் provider இல்லாமல் தவறுதலாக ஏதேனும் component-ஐ render செய்தாலும் அது உடையாது. Tests-இல் பல providers setup செய்யாமல் test environment-இல் உங்கள் components நன்றாக வேலை செய்யவும் இது உதவும்.
கீழுள்ள example-இல், “Theme மாற்று” button எப்போதும் light ஆக இருக்கும்; ஏனெனில் அது எந்த theme context provider-க்கும் வெளியே உள்ளது, மேலும் default context theme value 'light'. Default theme-ஐ 'dark' ஆக edit செய்து முயற்சிக்கவும்.
import { createContext, useContext, useState } from 'react'; const ThemeContext = createContext('light'); export default function MyApp() { const [theme, setTheme] = useState('light'); return ( <> <ThemeContext value={theme}> <Form /> </ThemeContext> <Button onClick={() => { setTheme(theme === 'dark' ? 'light' : 'dark'); }}> Theme மாற்று </Button> </> ) } function Form({ children }) { return ( <Panel title="வரவேற்பு"> <Button>பதிவு செய்</Button> <Button>உள்நுழை</Button> </Panel> ); } function Panel({ title, children }) { const theme = useContext(ThemeContext); const className = 'panel-' + theme; return ( <section className={className}> <h1>{title}</h1> {children} </section> ) } function Button({ children, onClick }) { const theme = useContext(ThemeContext); const className = 'button-' + theme; return ( <button className={className} onClick={onClick}> {children} </button> ); }
Tree-இன் ஒரு பகுதிக்காக context-ஐ override செய்தல்
Tree-இன் ஒரு பகுதியை வேறு value கொண்ட provider-க்குள் wrap செய்வதன் மூலம், அந்த பகுதிக்கான context-ஐ override செய்யலாம்.
<ThemeContext value="dark">
...
<ThemeContext value="light">
<Footer />
</ThemeContext>
...
</ThemeContext>தேவைப்படும் அளவுக்கு providers-ஐ nest செய்து override செய்யலாம்.
Example 1 of 2: Theme-ஐ override செய்தல்
இங்கே, Footer-க்கு உள்ளே இருக்கும் button, வெளியே உள்ள buttons ("dark") விட வேறுபட்ட context value ("light") பெறுகிறது.
import { createContext, useContext } from 'react'; const ThemeContext = createContext(null); export default function MyApp() { return ( <ThemeContext value="dark"> <Form /> </ThemeContext> ) } function Form() { return ( <Panel title="வரவேற்பு"> <Button>பதிவு செய்</Button> <Button>உள்நுழை</Button> <ThemeContext value="light"> <Footer /> </ThemeContext> </Panel> ); } function Footer() { return ( <footer> <Button>அமைப்புகள்</Button> </footer> ); } function Panel({ title, children }) { const theme = useContext(ThemeContext); const className = 'panel-' + theme; return ( <section className={className}> {title && <h1>{title}</h1>} {children} </section> ) } function Button({ children }) { const theme = useContext(ThemeContext); const className = 'button-' + theme; return ( <button className={className}> {children} </button> ); }
Objects மற்றும் functions pass செய்யும்போது re-renders-ஐ optimize செய்தல்
Objects மற்றும் functions உட்பட எந்த values-ஐயும் context வழியாக pass செய்யலாம்.
function MyApp() {
const [currentUser, setCurrentUser] = useState(null);
function login(response) {
storeCredentials(response.credentials);
setCurrentUser(response.user);
}
return (
<AuthContext value={{ currentUser, login }}>
<Page />
</AuthContext>
);
}இங்கே, context value இரண்டு properties கொண்ட JavaScript object; அவற்றில் ஒன்று function. MyApp re-render ஆகும் ஒவ்வொரு முறையும் (உதாரணமாக, route update-இல்), இது வேறு function-ஐச் சுட்டும் வேறு object ஆக இருக்கும். அதனால் useContext(AuthContext) call செய்யும் tree-இல் ஆழமான எல்லா components-ஐயும் React re-render செய்ய வேண்டி வரும்.
சிறிய apps-இல் இது பிரச்சினையல்ல. ஆனால் currentUser போன்ற underlying data மாறவில்லை என்றால், அவற்றை re-render செய்ய தேவையில்லை. அந்த உண்மையை React பயன்படுத்த உதவ, login function-ஐ useCallback-ஆல் wrap செய்து, object creation-ஐ useMemo-க்குள் wrap செய்யலாம். இது ஒரு performance optimization:
import { useCallback, useMemo } from 'react';
function MyApp() {
const [currentUser, setCurrentUser] = useState(null);
const login = useCallback((response) => {
storeCredentials(response.credentials);
setCurrentUser(response.user);
}, []);
const contextValue = useMemo(() => ({
currentUser,
login
}), [currentUser, login]);
return (
<AuthContext value={contextValue}>
<Page />
</AuthContext>
);
}இந்த மாற்றத்தின் விளைவாக, MyApp re-render ஆக வேண்டியிருந்தாலும், currentUser மாறாத வரை useContext(AuthContext) call செய்யும் components re-render ஆக வேண்டியதில்லை.
useMemo மற்றும் useCallback பற்றி மேலும் படிக்கவும்.
சிக்கல் தீர்வு
என் component என் provider-இலிருந்து value-ஐ பார்க்கவில்லை
இது நடக்கும் சில common வழிகள் உள்ளன:
useContext()call செய்யும் அதே component-இல் (அல்லது அதற்கு கீழே) நீங்கள்<SomeContext>render செய்கிறீர்கள்.useContext()call செய்யும் component-க்கு மேலாகவும் வெளியிலும்<SomeContext>-ஐ நகர்த்துங்கள்.- உங்கள் component-ஐ
<SomeContext>-ஆல் wrap செய்ய மறந்திருக்கலாம், அல்லது நீங்கள் நினைத்ததைவிட வேறு tree பகுதியில் அதை வைத்திருக்கலாம். React DevTools பயன்படுத்தி hierarchy சரியாக உள்ளதா என்று check செய்யுங்கள். - உங்கள் tooling-இல் உள்ள build issue காரணமாக, provide செய்யும் component பார்க்கும்
SomeContextமற்றும் read செய்யும் component பார்க்கும்SomeContextஇரண்டு வேறு objects ஆக இருக்கலாம். உதாரணமாக, symlinks use செய்தால் இது நடக்கலாம். அவற்றைwindow.SomeContext1மற்றும்window.SomeContext2போன்ற globals-க்கு assign செய்து, console-இல்window.SomeContext1 === window.SomeContext2என்பதை check செய்து இதை verify செய்யலாம். அவை ஒன்றாக இல்லையெனில், build tool level-இல் அந்த issue-ஐ fix செய்யுங்கள்.
Default value வேறாக இருந்தாலும் என் context-இலிருந்து எப்போதும் undefined கிடைக்கிறது
Tree-இல் value இல்லாத provider இருக்கலாம்:
// 🚩 Doesn't work: no value prop
<ThemeContext>
<Button />
</ThemeContext>value-ஐ specify செய்ய மறந்தால், அது value={undefined} pass செய்வது போலாகும்.
நீங்கள் தவறுதலாக வேறு prop பெயரையும் பயன்படுத்தியிருக்கலாம்:
// 🚩 Doesn't work: prop should be called "value"
<ThemeContext theme={theme}>
<Button />
</ThemeContext>இந்த இரு cases-இலும் console-இல் React-இலிருந்து warning காண வேண்டும். அவற்றை fix செய்ய, prop-ஐ value என்று அழைக்கவும்:
// ✅ Passing the value prop
<ThemeContext value={theme}>
<Button />
</ThemeContext>உங்கள் createContext(defaultValue) call-இலிருந்து வரும் default value மேலே பொருந்தும் provider ஒன்றும் இல்லாதபோது மட்டுமே use செய்யப்படும் என்பதை கவனிக்கவும். Parent tree-இல் எங்காவது <SomeContext value={undefined}> component இருந்தால், useContext(SomeContext) call செய்யும் component context value ஆக undefined-ஐப் பெறும்.