Õppige React Contexti meisterlikult selgeks, et hallata oma rakendustes olekuid tõhusalt. Siit saate teada, millal Contexti kasutada, kuidas seda efektiivselt rakendada ja vältida levinud vigu.
React Context: Põhjalik juhend
React Context on võimas funktsioon, mis võimaldab teil jagada andmeid komponentide vahel ilma, et peaksite prop'e (atribuute) selgesõnaliselt läbi iga komponendipuu taseme edasi andma. See pakub viisi, kuidas teha teatud väärtused kättesaadavaks kõigile komponentidele konkreetses alampuus. See juhend uurib, millal ja kuidas React Contexti tõhusalt kasutada, koos parimate tavade ja levinud vigadega, mida vältida.
Probleemi mõistmine: Prop Drilling
Keerulistes Reacti rakendustes võite kokku puutuda "prop drilling" probleemiga. See tekib siis, kui peate andmeid edastama vanemkomponendist sügavale pesastatud alamkomponendile. Selleks peate andmeid edastama läbi iga vahepealse komponendi, isegi kui need komponendid ise andmeid ei vaja. See võib viia:
- Koodi risustamiseni: Vahepealsed komponendid muutuvad üleliigsete prop'idega koormatuks.
- Hooldusraskusteni: Prop'i muutmine nõuab mitme komponendi muutmist.
- Vähenenud loetavuseni: Rakenduse andmevoo mõistmine muutub keerulisemaks.
Vaatleme seda lihtsustatud näidet:
function App() {
const user = { name: 'Alice', theme: 'dark' };
return (
<Layout user={user} />
);
}
function Layout({ user }) {
return (
<Header user={user} />
);
}
function Header({ user }) {
return (
<Navigation user={user} />
);
}
function Navigation({ user }) {
return (
<Profile user={user} />
);
}
function Profile({ user }) {
return (
<p>Tere tulemast, {user.name}!
Teema: {user.theme}</p>
);
}
Selles näites edastatakse user
objekt läbi mitme komponendi, kuigi seda kasutab tegelikult ainult Profile
komponent. See on klassikaline "prop drilling" juhtum.
Tutvustame React Contexti
React Context pakub viisi "prop drilling'u" vältimiseks, tehes andmed kättesaadavaks igale komponendile alampuus ilma neid selgesõnaliselt prop'ide kaudu edasi andmata. See koosneb kolmest põhiosast:
- Context: See on konteiner andmetele, mida soovite jagada. Contexti loote kasutades
React.createContext()
. - Provider: See komponent pakub andmeid context'ile. Iga komponent, mis on Provideri poolt ümbritsetud, pääseb ligi context'i andmetele. Provider aktsepteerib
value
prop'i, mis on andmed, mida soovite jagada. - Consumer: (Pärand, vähem levinud) See komponent tellib context'i. Iga kord, kui context'i väärtus muutub, renderdab Consumer uuesti. Consumer kasutab render prop funktsiooni, et pääseda ligi context'i väärtusele.
useContext
Hook: (Kaasaegne lähenemine) See hook võimaldab teil funktsionaalses komponendis otse context'i väärtusele ligi pääseda.
Millal kasutada React Contexti
React Context on eriti kasulik selliste andmete jagamiseks, mida peetakse Reacti komponentide puu jaoks "globaalseks". See võib hõlmata:
- Teema: Rakenduse teema (nt hele või tume režiim) jagamine kõigi komponentide vahel. Näide: Rahvusvaheline e-kaubanduse platvorm võib lubada kasutajatel vahetada heleda ja tumeda teema vahel, et parandada ligipääsetavust ja visuaalseid eelistusi. Context saab hallata ja pakkuda praegust teemat kõigile komponentidele.
- Kasutaja autentimine: Praeguse kasutaja autentimisoleku ja profiiliinfo pakkumine. Näide: Globaalne uudiste veebisait saab kasutada Contexti sisselogitud kasutaja andmete (kasutajanimi, eelistused jne) haldamiseks ja nende kättesaadavaks tegemiseks kogu saidil, võimaldades personaliseeritud sisu ja funktsioone.
- Keele-eelistused: Praeguse keelesätte jagamine rahvusvahelistamiseks (i18n). Näide: Mitmekeelne rakendus võiks kasutada Contexti hetkel valitud keele salvestamiseks. Komponendid pääsevad seejärel sellele context'ile ligi, et kuvada sisu õiges keeles.
- API klient: API kliendi eksemplari kättesaadavaks tegemine komponentidele, mis peavad tegema API-päringuid.
- Eksperimendi lipud (funktsioonide lülitid): Funktsioonide lubamine või keelamine konkreetsetele kasutajatele või gruppidele. Näide: Rahvusvaheline tarkvaraettevõte võib uusi funktsioone esmalt teatud piirkondade kasutajate alamhulgale välja anda, et testida nende toimivust. Context saab pakkuda neid funktsioonide lippe vastavatele komponentidele.
Olulised kaalutlused:
- Ei asenda kogu olekuhaldust: Context ei ole täisväärtusliku olekuhalduse teegi nagu Redux või Zustand asendaja. Kasutage Contexti andmete jaoks, mis on tõeliselt globaalsed ja muutuvad harva. Keerulise olekuloogika ja ennustatavate olekuvärskenduste jaoks on spetsiaalne olekuhalduse lahendus sageli sobivam. Näide: Kui teie rakendus hõlmab keerulise ostukorvi haldamist arvukate esemete, koguste ja arvutustega, võib olekuhalduse teek olla parem valik kui ainult Contextile tuginemine.
- Uuesti renderdamised: Kui context'i väärtus muutub, renderdatakse uuesti kõik komponendid, mis seda context'i tarbivad. See võib mõjutada jõudlust, kui context'i uuendatakse sageli või kui tarbivad komponendid on keerulised. Optimeerige oma context'i kasutust, et minimeerida tarbetuid uuesti renderdamisi. Näide: Reaalajas rakenduses, mis kuvab sageli uuenevaid aktsiahindu, võib aktsiahinna context'i tellinud komponentide tarbetu uuesti renderdamine jõudlust negatiivselt mõjutada. Kaaluge memoiseerimistehnikate kasutamist, et vältida uuesti renderdamist, kui asjakohased andmed pole muutunud.
Kuidas React Contexti kasutada: praktiline näide
Vaatame uuesti "prop drilling'u" näidet ja lahendame selle React Contexti abil.
1. Looge Context
Esmalt looge context, kasutades React.createContext()
. See context hoiab kasutaja andmeid.
// UserContext.js
import React from 'react';
const UserContext = React.createContext(null); // Vaikimisi väärtus võib olla null või algne kasutaja objekt
export default UserContext;
2. Looge Provider
Järgmiseks mähkige oma rakenduse juur (või asjakohane alampuu) UserContext.Provider
'iga. Edastage user
objekt Providerile value
prop'ina.
// App.js
import React from 'react';
import UserContext from './UserContext';
import Layout from './Layout';
function App() {
const user = { name: 'Alice', theme: 'dark' };
return (
<UserContext.Provider value={user}>
<Layout />
</UserContext.Provider>
);
}
export default App;
3. Tarbige Contexti
Nüüd pääseb Profile
komponent user
andmetele otse context'ist ligi, kasutades useContext
hook'i. Enam pole vaja prop'e edasi anda!
// Profile.js
import React, { useContext } from 'react';
import UserContext from './UserContext';
function Profile() {
const user = useContext(UserContext);
return (
<p>Tere tulemast, {user.name}!
Teema: {user.theme}</p>
);
}
export default Profile;
Vahepealsed komponendid (Layout
, Header
ja Navigation
) ei pea enam user
prop'i vastu võtma.
// Layout.js, Header.js, Navigation.js
import React from 'react';
function Layout({ children }) {
return (
<div>
<Header />
<main>{children}</main>
</div>
);
}
function Header() {
return (<Navigation />);
}
function Navigation() {
return (<Profile />);
}
export default Layout;
Täpsem kasutus ja parimad tavad
1. Contexti kombineerimine useReducer
'iga
Keerulisema olekuhalduse jaoks saate kombineerida React Contexti useReducer
hook'iga. See võimaldab teil hallata olekuvärskendusi ennustatavamal ja hooldatavamal viisil. Context pakub olekut ja reducer tegeleb olekumuutustega, mis põhinevad saadetud tegevustel (actions).
// ThemeContext.js import React, { createContext, useReducer } from 'react'; const ThemeContext = createContext(); const initialState = { theme: 'light' }; const themeReducer = (state, action) => { switch (action.type) { case 'TOGGLE_THEME': return { ...state, theme: state.theme === 'light' ? 'dark' : 'light' }; default: return state; } }; function ThemeProvider({ children }) { const [state, dispatch] = useReducer(themeReducer, initialState); return ( <ThemeContext.Provider value={{ ...state, dispatch }}> {children} </ThemeContext.Provider> ); } export { ThemeContext, ThemeProvider };
// ThemeToggle.js import React, { useContext } from 'react'; import { ThemeContext } from './ThemeContext'; function ThemeToggle() { const { theme, dispatch } = useContext(ThemeContext); return ( <button onClick={() => dispatch({ type: 'TOGGLE_THEME' })}> Vaheta teemat (Praegune: {theme}) </button> ); } export default ThemeToggle;
// App.js import React from 'react'; import { ThemeProvider } from './ThemeContext'; import ThemeToggle from './ThemeToggle'; function App() { return ( <ThemeProvider> <div> <ThemeToggle /> </div> </ThemeProvider> ); } export default App;
2. Mitu Contexti
Saate oma rakenduses kasutada mitut context'i, kui teil on vaja hallata erinevat tüüpi globaalseid andmeid. See aitab hoida teie mured lahus ja parandab koodi organiseeritust. Näiteks võib teil olla UserContext
kasutaja autentimiseks ja ThemeContext
rakenduse teema haldamiseks.
3. Jõudluse optimeerimine
Nagu varem mainitud, võivad context'i muudatused käivitada tarbivates komponentides uuesti renderdamise. Jõudluse optimeerimiseks kaaluge järgmist:
- Memoiseerimine: Kasutage
React.memo
, et vältida komponentide tarbetut uuesti renderdamist. - Stabiilsed Contexti väärtused: Veenduge, et Providerile edastatud
value
prop on stabiilne viide. Kui väärtus on igal renderdamisel uus objekt või massiiv, põhjustab see tarbetuid uuesti renderdamisi. - Valikulised uuendused: Uuendage context'i väärtust ainult siis, kui see tegelikult muutuma peab.
4. Kohandatud Hookide kasutamine Contextile juurdepääsuks
Looge kohandatud hook'e, et kapseldada context'i väärtustele juurdepääsu ja nende uuendamise loogika. See parandab koodi loetavust ja hooldatavust. Näiteks:
// useTheme.js import { useContext } from 'react'; import { ThemeContext } from './ThemeContext'; function useTheme() { const context = useContext(ThemeContext); if (!context) { throw new Error('useTheme peab olema kasutatud ThemeProvideri sees'); } return context; } export default useTheme;
// MyComponent.js import React from 'react'; import useTheme from './useTheme'; function MyComponent() { const { theme, dispatch } = useTheme(); return ( <div> Praegune teema: {theme} <button onClick={() => dispatch({ type: 'TOGGLE_THEME' })}> Vaheta teema </button> </div> ); } export default MyComponent;
Levinud vead, mida vältida
- Contexti liigne kasutamine: Ärge kasutage Contexti kõige jaoks. See sobib kõige paremini andmetele, mis on tõeliselt globaalsed.
- Keerulised uuendused: Vältige keeruliste arvutuste või kõrvalmõjude teostamist otse context provider'is. Kasutage nende operatsioonide haldamiseks reducer'it või muud olekuhalduse tehnikat.
- Jõudluse ignoreerimine: Olge Contexti kasutamisel teadlik jõudlusmõjudest. Optimeerige oma koodi, et minimeerida tarbetuid uuesti renderdamisi.
- Vaikimisi väärtuse mitte andmine: Kuigi see on valikuline, aitab vaikimisi väärtuse andmine
React.createContext()
-le vältida vigu, kui komponent proovib tarbida context'i väljaspool Providerit.
Alternatiivid React Contextile
Kuigi React Context on väärtuslik tööriist, ei ole see alati parim lahendus. Kaaluge neid alternatiive:
- Prop Drilling (mõnikord): Lihtsate juhtumite puhul, kus andmeid on vaja vaid mõnel komponendil, võib prop'ide edasiandmine olla lihtsam ja tõhusam kui Contexti kasutamine.
- Olekuhalduse teegid (Redux, Zustand, MobX): Keeruliste rakenduste puhul, millel on keerukas olekuloogika, on spetsiaalne olekuhalduse teek sageli parem valik.
- Komponentide kompositsioon: Kasutage komponentide kompositsiooni, et andmeid kontrollitumal ja selgesõnalisemal viisil läbi komponendipuu edasi anda.
Kokkuvõte
React Context on võimas funktsioon andmete jagamiseks komponentide vahel ilma "prop drilling'uta". Selle tõhus kasutamine on hooldatavate ja jõudluspõhiste Reacti rakenduste ehitamisel ülioluline. Järgides selles juhendis toodud parimaid tavasid ja vältides levinud vigu, saate React Contexti abil oma koodi parendada ja luua parema kasutajakogemuse. Ärge unustage hinnata oma konkreetseid vajadusi ja kaaluda alternatiive enne, kui otsustate Contexti kasutada.