![]()
A Refs egy React szolgáltatás, amely lehetővé teszi a komponensek által létrehozott DOM csomópontok közvetlen elérését render() módszer. Lehetővé teszik a React deklaratív megjelenítéséből való kitörést, így hívhatja a böngésző API-kat.
A React használatakor általában kijelenti, hogy egy komponens DOM-nak hogyan kell kinéznie a JSX használatával:
class MyComponent extends React.Component { state = {value: ""}; handleChange = e => this.setState({value: e.target.value}); render() { return ( <div> <h1>Hello World!</h1> <input onChange={this.handleChange} value={this.state.value} /> </div> ); } };
A React belsőleg átülteti a JSX-t, hogy kidolgozza a DOM manipulálását. Olyan böngészőfunkciókat fog használni, mint a document.createElement() és document.appendChild() a deklarált DOM struktúra létrehozásához.
Ez jelentősen leegyszerűsíti a DOM programszerű frissítéséhez szükséges kódot. Az elemek módosításához módosítsa azok kellékeit, vagy frissítse az összetevők állapotát. Ezután a React kiszámítja a különbségeket, és szükségessé teszi a DOM beállításait.
A referenciák esete
Rendszerint nem fér hozzá a React által létrehozott DOM-csomópontokhoz. A fenti példában nincs kezünk az általunk létrehozott elemekkel. Ez akkor válik problematikussá, ha olyan DOM API-t szeretne meghívni, amelyhez a React kellékek segítségével nem lehet deklaratív módon hozzáférni.
Vizsgáljuk meg, mi történik, ha a felhasználó érvénytelen értéket ír be a szövegbevitelbe. Ha ezután valódi formában kattintanak a beküldésre, akkor célszerű hibaüzenetet megjeleníteni, és a fókuszt visszahelyezni a szövegbevitelbe. Ezt nem teheti meg, ha nem fér hozzá a bemenet DOM csomópontjához. Fel kell hívnia a focus() módszer az adott elemre.
Adja meg a hivatkozásokat. A Refs első osztályú módot kínál arra, hogy „hivatkozást” szerezzen a React DOM csomópontjaira. A fókuszproblémát úgy oldhatja meg, hogy a bemenethez hozzárendel egy hivatkozást. A referenciák a current tulajdonság, amely tartalmazza az általuk hivatkozott DOM csomópontot.
Ref létrehozása
A referenciákat általában kifejezetten hívással hozzák létre React.createRef(). Ezután a special használatával hozzárendeli őket egy összetevő példányhoz ref támaszt. Ez nem igazi kellék, és az összetevő nem érheti el.
class DemoComponent extends React.Component { inputRef = React.createRef(); focusInput = () => this.inputRef?.current.focus(); render() { return ( <div> <input ref={this.inputRef} /> <button onClick={this.focusInput} /> </div> ); } }
A ref hozzárendelésre kerül a példány tulajdonsághoz inputRef. Ezt aztán átadják a input elemet annak beállításával ref támaszt. A gombra kattintva a focusInput() metódust hívják meg. Ez hozzáfér a current a ref tulajdonság, amely tartalmazza az input tényleges DOM csomópontját. Most már hívhat focus() a szövegmező fókuszálásához.
A current a referenciák tulajdonsága lehet null. Ez akkor fordul elő, ha a hivatkozás nincs hozzárendelve renderelt DOM elemhez. Ebben a példában inputRef.current lesz null amíg a render() metódust hívják meg, és az input felveszi a ref. Emiatt a opcionális láncolás operátor (?.) használják focusInput() kecsesen kezelni azt a forgatókönyvet, ahol a hivatkozás még nem utal semmire.
Ref-ek hozzárendelése a reaktív komponensekhez
A fenti példa bemutatja, hogyan működnek a referenciák egyszerű HTML elemekkel együtt. A React összetevő példányokhoz is rendelhet ref. Ez lehetővé teszi, hogy közvetlenül meghívja a renderelt gyermekek által meghatározott módszereket.
class View extends React.Component { state = { error: true; // Example! }; formRef = React.createRef(); focusForm = () => this.formRef?.current.focusInput(); submit = () => { if (this.state.error) { alert("There was an error; check your input."); this.focusForm(); } }; render() { return ( <div> <Form ref={this.formRef} /> <Button onClick={this.submit} /> </div> ); } } class Form extends React.Component { inputRef = React.createRef(); focusInput() { this.inputRef.current?.focus(); } render() { return <input ref={this.inputRef} /> } }
Ebben a forgatókönyvben a current tulajdona formRef ban ben View nem utal DOM csomópontra. Ehelyett a Form komponens példányt, amelyet rendereltek.
Legyen óvatos, ha ezt a megközelítést használja. Az adatokat mindig továbbítsa a gyermekkomponenseknek a kellékek segítségével, ahelyett, hogy visszahívási rendszerként használná a ref-eket.
Általában ref-t kell használni, ha a DOM közvetlen interakciója elkerülhetetlen. Ez akkor is igaz, ha a React összetevő példányhoz ref-t rendelünk. Nem szabad tetszőleges komponens metódusokat hivatkozással meghívni.
Példánk megfelel ennek a követelménynek – Form egy prezentációs komponens, míg View egy összetett tároló, amely több formát képes megjeleníteni. Képesnek kell lennie a problémás területekre fókuszálni, annak ellenére, hogy nem közvetlenül adja meg őket. A megoldás az alkatrészek ref-jének körültekintő használata, biztosítva, hogy a felhasználást a DOM manipulálásának szükségessége indokolja.
Refs és funkcionális alkatrészek
A funkcionális alkatrészek nem tudnak referenciákat kapni. Nincsenek példányaik, így nincs mit hozzárendelni a ref-hez. Te azonban tud használja a továbbítást a hivatkozás átirányításához egy DOM-összetevőhöz.
Az átirányítás egy olyan opcionális szolgáltatás, amely lehetővé teszi, hogy az összetevő átadja a kapott ref-t az általa nyújtott gyermekek egyikének. Ref-továbbításhoz csomagolja az összetevőt egy hívással a React-hez forwardRef() funkció:
const InputComponent = React.forwardRef((props, ref) => ( <input ref={ref} value={props.value} /> ));
forwardRef() elfogad egy olyan függvényt, amelynek vissza kell adnia a React komponenst. A függvény akkor lesz meghívva, amikor renderelnie kell, és két paramétert ad át neki: a kellékeit és a továbbított ref.
Ref-ek használata a funkcionális komponenseken belül
Noha a funkcionális komponensek nem tudnak közvetlenül referenciákat kapni, a useRef() horog. Ez egyenértékű a createRef() osztálykomponensekben elérhető módszer.
const InputComponent = props => { const ref = useRef(); return <input ref={ref} value={props.value} /> };
Fontos, useRef() többre használható mint csak refs. Valódi szerepe az, hogy a funkcionális komponens felé irányuló hívások között megőrizze az adatokat. Egy objektumot ad vissza a-val current az a tulajdonság, amelyet a React minden egyes alkatrész rendereléskor megtart és visszaállít.
Ezért használhatja useRef() tetszőleges adatok megőrzése a funkcionális komponensekben. Állítsa be a current a visszaküldött objektum tulajdonságát arra az értékre, amelyet körül akar tartani.
Visszahívási hivatkozások
A ref-ekkel való munka végső módja a „visszahívási” minta. Ezzel a megközelítéssel nem kell manuálisan hívnia createRef() vagy useRef(). Ehelyett beállítja a ref prop egy olyan függvényhez, amelyet a React a renderelés során meghív. Az elem DOM csomópontját fogja továbbadni egyetlen függvényként.
class CallbackRef extends React.Component { render() { return <input ref={el => this.inputRef = el} /> } }
Ez egy tömörebb módszer a példánytulajdonságokhoz rendelt hivatkozások létrehozására. A funkciója közvetlenül megkapja a DOM csomópontot – nincs .current kezelni, ellentétben createRef().
Következtetés
A React Refs segítségével olyan eseteket kezelhet, amelyeket egyedül a deklaratív megjelenítéssel nem tudna megoldani. Ezek az útvonalak a DOM közvetlen kezeléséhez, amikor űrlapokkal, médialejátszással és animációkkal dolgoznak. Akkor is találhatja magát a referenciák után, ha integrálnia kell egy harmadik féltől származó JavaScript könyvtárat, amelyet nem a React számára készítettek.
Bár a referenciák rugalmasak, nem szabad túlzásba vinni őket. A referencia létrehozása előtt ellenőrizze az összetevőket, hogy megbizonyosodjon arról, hogy deklaráltan nem tudja elérni a célját.
A referenciák a React szükséges része, de ellentmondanak a könyvtár alapelveinek. A túl sok hivatkozás bonyolulttá teheti alkalmazásod karbantartását. Lehetővé teszik az alulról lefelé irányuló adatfolyam megszakítását, amelyet a kellékek általában érvényesítenek.
