Išsamus React useSyncExternalStore kabliuko vadovas, nagrinėjantis jo paskirtį, įgyvendinimą, privalumus ir pažangius naudojimo atvejus išorinei būsenai valdyti.
React useSyncExternalStore: Išorinės būsenos sinchronizavimo įvaldymas
useSyncExternalStore
yra React kabliukas, pristatytas React 18 versijoje, leidžiantis prenumeruoti ir skaityti duomenis iš išorinių duomenų šaltinių taip, kad būtų suderinama su konkurentiniu atvaizdavimu. Šis kabliukas užpildo spragą tarp React valdomos būsenos ir išorinės būsenos, tokios kaip duomenys iš trečiųjų šalių bibliotekų, naršyklės API ar kitų UI sistemų. Giliai pasinerkime į jo paskirties, įgyvendinimo ir privalumų supratimą.
useSyncExternalStore poreikio supratimas
React įmontuotas būsenos valdymas (useState
, useReducer
, Context API) puikiai veikia duomenims, glaudžiai susijusiems su React komponentų medžiu. Tačiau daugelis programų turi integruotis su duomenų šaltiniais, esančiais *už* React kontrolės ribų. Šie išoriniai šaltiniai gali būti:
- Trečiųjų šalių būsenos valdymo bibliotekos: Integracija su tokiomis bibliotekomis kaip Zustand, Jotai arba Valtio.
- Naršyklės API: Prieiga prie duomenų iš
localStorage
,IndexedDB
arba Network Information API. - Duomenys, paimti iš serverių: Nors tokios bibliotekos kaip React Query ir SWR dažnai yra pageidaujamos, kartais galite norėti tiesioginės kontrolės.
- Kitos UI sistemos: Hibridinėse programose, kuriose React egzistuoja kartu su kitomis UI technologijomis.
Tiesioginis skaitymas ir rašymas į šiuos išorinius šaltinius React komponente gali sukelti problemų, ypač su konkurentiniu atvaizdavimu. React gali atvaizduoti komponentą su pasenusiais duomenimis, jei išorinis šaltinis pasikeičia, kol React ruošia naują ekraną. useSyncExternalStore
išsprendžia šią problemą, suteikdamas React mechanizmą saugiai sinchronizuoti su išorine būsena.
Kaip veikia useSyncExternalStore
useSyncExternalStore
kabliukas priima tris argumentus:
subscribe
: Funkcija, kuri priima atgalinį iškvietimą. Šis atgalinis iškvietimas bus iškviestas, kai tik pasikeis išorinė saugykla. Funkcija turėtų grąžinti funkciją, kuri, kai bus iškviesta, atšauks prenumeratą iš išorinės saugyklos.getSnapshot
: Funkcija, kuri grąžina dabartinę išorinės saugyklos vertę. React naudoja šią funkciją, norėdamas perskaityti saugyklos vertę atvaizdavimo metu.getServerSnapshot
(nebūtina): Funkcija, kuri grąžina pradinę išorinės saugyklos vertę serveryje. Tai būtina tik serverio pusės atvaizdavimui (SSR). Jei nenurodyta, React serveryje naudosgetSnapshot
.
Kabliukas grąžina dabartinę išorinės saugyklos vertę, gautą iš getSnapshot
funkcijos. React užtikrina, kad komponentas bus iš naujo atvaizduojamas, kai tik pasikeis getSnapshot
grąžinta vertė, kaip nustatyta Object.is
palyginimu.
Pagrindinis pavyzdys: sinchronizavimas su localStorage
Sukurkime paprastą pavyzdį, kuris naudoja useSyncExternalStore
, norėdamas sinchronizuoti vertę su localStorage
.
Vertė iš localStorage: {localValue}
Šiame pavyzdyje:
subscribe
: Klausostorage
įvykio antwindow
objekto. Šis įvykis suaktyvinamas, kai tiklocalStorage
yra modifikuojamas kitoje kortelėje arba lange.getSnapshot
: GaunamyValue
vertę išlocalStorage
.getServerSnapshot
: Grąžina numatytąją vertę serverio pusės atvaizdavimui. Tai galima gauti iš slapuko, jei vartotojas anksčiau buvo nustatęs vertę.MyComponent
: NaudojauseSyncExternalStore
, kad prenumeruotųlocalStorage
pakeitimus ir rodytų dabartinę vertę.
Pažangūs naudojimo atvejai ir svarstymai
1. Integracija su trečiųjų šalių būsenos valdymo bibliotekomis
useSyncExternalStore
puikiai tinka integruojant React komponentus su išorinėmis būsenos valdymo bibliotekomis. Pažvelkime į pavyzdį naudodami Zustand:
Skaičius: {count}
Šiame pavyzdyje, useSyncExternalStore
yra naudojamas prenumeruoti Zustand saugyklos pakeitimus. Atkreipkite dėmesį, kaip mes perduodame useStore.subscribe
ir useStore.getState
tiesiogiai kabliukui, todėl integracija yra sklandi.
2. Našumo optimizavimas naudojant įsiminimą
Kadangi getSnapshot
yra iškviečiamas kiekvieno atvaizdavimo metu, būtina užtikrinti, kad jis būtų našus. Venkite brangių skaičiavimų getSnapshot
viduje. Jei reikia, įsiminkite getSnapshot
rezultatą naudodami useMemo
arba panašius metodus.
Apsvarstykite šį (potencialiai problematišką) pavyzdį:
```javascript import { useSyncExternalStore, useMemo } from 'react'; const externalStore = { data: [...Array(10000).keys()], // Didelis masyvas listeners: [], subscribe(listener) { this.listeners.push(listener); return () => { this.listeners = this.listeners.filter((l) => l !== listener); }; }, setState(newData) { this.data = newData; this.listeners.forEach((listener) => listener()); }, getState() { return this.data; }, }; function ExpensiveComponent() { const data = useSyncExternalStore( externalStore.subscribe, () => externalStore.getState().map(x => x * 2) // Brangi operacija ); return (-
{data.slice(0, 10).map((item) => (
- {item} ))}
Šiame pavyzdyje getSnapshot
(įdėtoji funkcija, perduota kaip antrasis argumentas useSyncExternalStore
) atlieka brangią map
operaciją su dideliu masyvu. Ši operacija bus vykdoma *kiekvieno* atvaizdavimo metu, net jei pagrindiniai duomenys nepasikeitė. Norėdami tai optimizuoti, galime įsiminti rezultatą:
-
{data.slice(0, 10).map((item) => (
- {item} ))}
Dabar map
operacija atliekama tik tada, kai pasikeičia externalStore.getState()
. Pastaba: jums iš tikrųjų reikės giliai palyginti `externalStore.getState()` arba naudoti skirtingą strategiją, jei saugykla mutuoja tą patį objektą. Pavyzdys yra supaprastintas demonstracijai.
3. Konkurentinio atvaizdavimo tvarkymas
Pagrindinis useSyncExternalStore
privalumas yra jo suderinamumas su React konkurentinio atvaizdavimo funkcijomis. Konkurentinis atvaizdavimas leidžia React vienu metu paruošti kelias UI versijas. Kai išorinė saugykla pasikeičia konkurentinio atvaizdavimo metu, useSyncExternalStore
užtikrina, kad React visada naudos naujausius duomenis, kai įsipareigoja pakeitimus DOM.
Be useSyncExternalStore
, komponentai gali būti atvaizduojami su pasenusiais duomenimis, dėl ko atsiranda vaizdinių neatitikimų ir netikėto elgesio. useSyncExternalStore
getSnapshot
metodas yra sukurtas būti sinchroninis ir greitas, leidžiantis React greitai nustatyti, ar išorinė saugykla pasikeitė atvaizdavimo metu.
4. Serverio pusės atvaizdavimo (SSR) svarstymai
Kai naudojate useSyncExternalStore
su serverio pusės atvaizdavimu, būtina pateikti getServerSnapshot
funkciją. Ši funkcija naudojama norint gauti pradinę išorinės saugyklos vertę serveryje. Be jos, React bandys naudoti getSnapshot
serveryje, o tai gali būti neįmanoma, jei išorinė saugykla priklauso nuo naršyklei būdingų API (pvz., localStorage
).
getServerSnapshot
funkcija turėtų grąžinti numatytąją vertę arba gauti duomenis iš serverio pusės šaltinio (pvz., slapukai, duomenų bazė). Tai užtikrina, kad pradinis HTML, atvaizduotas serveryje, turės teisingus duomenis.
5. Klaidų tvarkymas
Patikimas klaidų tvarkymas yra labai svarbus, ypač kai dirbate su išoriniais duomenų šaltiniais. Apvyniokite getSnapshot
ir getServerSnapshot
funkcijas try...catch
blokais, kad tvarkytumėte galimas klaidas. Atitinkamai registruokite klaidas ir pateikite atsargines vertes, kad programa neatsijungtų.
6. Pasirinktiniai kabliukai pakartotiniam naudojimui
Norėdami skatinti kodo pakartotinį naudojimą, apibendrinkite useSyncExternalStore
logiką pasirinktiniame kabliuke. Tai palengvina logikos bendrinimą tarp kelių komponentų.
Pavyzdžiui, sukurkime pasirinktinį kabliuką, skirtą pasiekti konkretų raktą localStorage
:
Dabar galite lengvai naudoti šį kabliuką bet kuriame komponente:
```javascript import useLocalStorage from './useLocalStorage'; function MyComponent() { const [name, setName] = useLocalStorage('userName', 'Guest'); return (Sveiki, {name}!
setName(e.target.value)} />Geriausios praktikos
- Laikykite
getSnapshot
greitą: Venkite brangių skaičiavimųgetSnapshot
funkcijoje. Įsiminkite rezultatą, jei reikia. - Pateikite
getServerSnapshot
SSR: Užtikrinkite, kad pradinis HTML, atvaizduotas serveryje, turės teisingus duomenis. - Naudokite pasirinktinius kabliukus: Apibendrinkite
useSyncExternalStore
logiką pasirinktiniuose kabliukuose, kad būtų lengviau pakartotinai naudoti ir prižiūrėti. - Tvarkykite klaidas grakščiai: Apvyniokite
getSnapshot
irgetServerSnapshot
try...catch
blokais. - Sumažinkite prenumeratas: Prenumeruokite tik tas išorinės saugyklos dalis, kurių komponentui iš tikrųjų reikia. Tai sumažina nereikalingus pakartotinius atvaizdavimus.
- Apsvarstykite alternatyvas: Įvertinkite, ar tikrai reikia
useSyncExternalStore
. Paprastais atvejais kitos būsenos valdymo technikos gali būti tinkamesnės.
Alternatyvos useSyncExternalStore
Nors useSyncExternalStore
yra galingas įrankis, jis ne visada yra geriausias sprendimas. Apsvarstykite šias alternatyvas:
- Įmontuotas būsenos valdymas (
useState
,useReducer
, Context API): Jei duomenys yra glaudžiai susiję su React komponentų medžiu, šių įmontuotų parinkčių dažnai pakanka. - React Query/SWR: Duomenų gavimui šios bibliotekos suteikia puikų talpyklos, anuliavimo ir klaidų tvarkymo pajėgumus.
- Zustand/Jotai/Valtio: Šios minimalistinės būsenos valdymo bibliotekos siūlo paprastą ir efektyvų būdą valdyti programos būseną.
- Redux/MobX: Sudėtingoms programoms su globalia būsena, Redux arba MobX gali būti geresnis pasirinkimas (nors jie įveda daugiau šablonų).
Pasirinkimas priklauso nuo konkrečių jūsų programos reikalavimų.
Išvada
useSyncExternalStore
yra vertingas React įrankių rinkinio papildymas, leidžiantis sklandžiai integruotis su išoriniais būsenos šaltiniais, išlaikant suderinamumą su konkurentiniu atvaizdavimu. Suprasdami jo paskirtį, įgyvendinimą ir pažangius naudojimo atvejus, galite panaudoti šį kabliuką, norėdami kurti patikimas ir našias React programas, kurios efektyviai sąveikauja su duomenimis iš įvairių šaltinių.
Nepamirškite teikti pirmenybę našumui, tvarkyti klaidas grakščiai ir apsvarstyti alternatyvius sprendimus prieš pasiekiant useSyncExternalStore
. Kruopščiai planuojant ir įgyvendinant, šis kabliukas gali žymiai padidinti jūsų React programų lankstumą ir galią.
Tolesnis tyrinėjimas
- React dokumentacija apie useSyncExternalStore
- Pavyzdžiai su įvairiomis būsenos valdymo bibliotekomis (Zustand, Jotai, Valtio)
- Našumo etalonai, lyginantys
useSyncExternalStore
su kitais požiūriais