En omfattende guide, der udforsker React Refs med fokus på useRef og createRef. Lær hvordan og hvornår du skal bruge hver især til effektiv komponentstyring og DOM-adgang i globale applikationer.
React Refs: Afmystificering af useRef vs. createRef
I den dynamiske verden af React-udvikling er det afgørende effektivt at styre komponenttilstand og interagere med Document Object Model (DOM). React Refs giver en mekanisme til at få adgang til og manipulere DOM-elementer eller React-komponenter direkte. To primære metoder til at oprette Refs er useRef
og createRef
. Selvom begge tjener formålet med at oprette Refs, er de forskellige i deres implementering og anvendelsestilfælde. Denne guide har til formål at afmystificere disse to tilgange og give klarhed over, hvornår og hvordan du effektivt kan udnytte hver især i dine React-projekter, især når du udvikler til et globalt publikum.
Forståelse af React Refs
En Ref (forkortelse for reference) er en React-funktion, der giver dig mulighed for at få adgang til en DOM-node eller en React-komponent direkte. Dette er især nyttigt, når du har brug for at:
- Manipulere et DOM-element direkte, f.eks. ved at fokusere et inputfelt.
- Få adgang til en underkomponents metoder eller egenskaber.
- Administrere værdier, der fortsætter på tværs af gengivelser uden at forårsage gengivelser (svarende til instansvariabler i klassekomponenter).
Selvom React tilskynder til en deklarativ tilgang, hvor UI styres gennem tilstand og props, er der situationer, hvor direkte manipulation er nødvendig. Refs giver en måde at bygge bro mellem Reacts deklarative natur og imperative DOM-operationer.
createRef
: Klassekomponenttilgangen
createRef
er en metode, der leveres af React. Den bruges primært i klassekomponenter til at oprette Refs. Hver gang en klassekomponent instantieres, opretter createRef
et nyt Ref-objekt. Dette sikrer, at hver instans af komponenten har sin egen unikke Ref.
Syntaks og brug
For at bruge createRef
skal du først erklære en Ref i din klassekomponent, typisk i konstruktøren. Derefter vedhæfter du Ref til et DOM-element eller en komponent ved hjælp af attributten ref
.
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
componentDidMount() {
// Access the DOM element after the component mounts
this.myRef.current.focus();
}
render() {
return <input type="text" ref={this.myRef} />;
}
}
I dette eksempel oprettes this.myRef
ved hjælp af React.createRef()
. Den tildeles derefter attributten ref
for inputelementet. Når komponenten er monteret (i componentDidMount
), kan du få adgang til den faktiske DOM-node ved hjælp af this.myRef.current
og udføre operationer på den (i dette tilfælde fokusere input).
Eksempel: Fokus på et inputfelt
Lad os overveje et scenarie, hvor du automatisk vil fokusere et inputfelt, når en komponent monteres. Dette er et almindeligt anvendelsestilfælde for Refs, især i formularer eller interaktive elementer.
class FocusInput extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
componentDidMount() {
this.inputRef.current.focus();
}
render() {
return (
<div>
<input type="text" ref={this.inputRef} />
</div>
);
}
}
I dette eksempel fokuserer FocusInput
inputfeltet umiddelbart efter montering. Dette kan forbedre brugeroplevelsen ved at rette brugerens opmærksomhed mod inputelementet, så snart komponenten gengives.
Vigtige overvejelser med createRef
- Kun klassekomponenter:
createRef
er designet til brug i klassekomponenter. Selvom det teknisk set kan fungere i funktionelle komponenter, er det ikke den tilsigtede brug og kan føre til uventet opførsel. - Ny Ref for hver instans: Hver instans af en klassekomponent får sin egen
createRef
. Dette er vigtigt for at opretholde isolation mellem komponentinstanser.
useRef
: Functional Component Hook
useRef
er en Hook, der blev introduceret i React 16.8. Det giver en måde at oprette mutable Ref-objekter i funktionelle komponenter. I modsætning til createRef
returnerer useRef
det samme Ref-objekt, hver gang komponenten gengives. Dette gør det ideelt til at fastholde værdier på tværs af gengivelser uden at udløse gengivelser.
Syntaks og brug
Det er ligetil at bruge useRef
. Du kalder Hook useRef
og sender en startværdi. Hook returnerer et objekt med en .current
-egenskab, som du derefter kan bruge til at få adgang til og ændre værdien.
import React, { useRef, useEffect } from 'react';
function MyFunctionalComponent() {
const myRef = useRef(null);
useEffect(() => {
// Access the DOM element after the component mounts
if (myRef.current) {
myRef.current.focus();
}
}, []);
return <input type="text" ref={myRef} />;
}
I dette eksempel opretter useRef(null)
en Ref med en startværdi på null
. Hook useEffect
bruges til at få adgang til DOM-elementet, efter at komponenten er monteret. Egenskaben myRef.current
indeholder referencen til inputelementet, så du kan fokusere det.
Eksempel: Sporing af tidligere propværdier
Et kraftfuldt anvendelsestilfælde for useRef
er at spore den tidligere værdi af en prop. Da ændringer af Refs ikke udløser gengivelser, kan du bruge dem til at gemme værdier, som du vil fastholde på tværs af gengivelser uden at påvirke UI.
import React, { useRef, useEffect } from 'react';
function PreviousValueComponent({ value }) {
const previousValue = useRef();
useEffect(() => {
previousValue.current = value;
}, [value]);
return (
<div>
<p>Current Value: {value}</p>
<p>Previous Value: {previousValue.current}</p>
</div>
);
}
I dette eksempel gemmer previousValue.current
den tidligere værdi af value
-prop. Hook useEffect
opdaterer Ref, når value
-prop ændres. Dette giver dig mulighed for at sammenligne de aktuelle og tidligere værdier, hvilket kan være nyttigt til at registrere ændringer eller implementere animationer.
Vigtige overvejelser med useRef
- Kun funktionelle komponenter:
useRef
er en Hook og kan kun bruges i funktionelle komponenter eller brugerdefinerede Hooks. - Fastholdes på tværs af gengivelser: Hook
useRef
returnerer det samme Ref-objekt ved hver gengivelse. Dette er nøglen til dens evne til at fastholde værdier uden at udløse gengivelser. - Mutable
.current
-egenskab: Du kan direkte ændre.current
-egenskaben for Ref-objektet. - Startværdi: Du kan angive en startværdi for
useRef
. Denne værdi tildeles egenskaben.current
, når komponenten først gengives. - Ingen gengivelser: Ændring af
.current
-egenskaben for en Ref forårsager ikke en komponentgengivelse.
useRef
vs. createRef
: En detaljeret sammenligning
Nu hvor vi har udforsket både useRef
og createRef
individuelt, lad os sammenligne dem side om side for at fremhæve deres vigtigste forskelle og hvornår man skal vælge den ene frem for den anden.
Funktion | useRef |
createRef |
---|---|---|
Komponenttype | Funktionelle komponenter | Klassekomponenter |
Hook eller metode | Hook | Metode |
Ref-instans | Returnerer det samme Ref-objekt ved hver gengivelse | Opretter et nyt Ref-objekt ved hver instans af komponenten |
Anvendelsestilfælde |
|
|
Valg af den rigtige Ref: En beslutningsguide
Her er en simpel guide, der hjælper dig med at vælge mellem useRef
og createRef
:
- Arbejder du med en funktionel komponent? Brug
useRef
. - Arbejder du med en klassekomponent? Brug
createRef
. - Har du brug for at fastholde en værdi på tværs af gengivelser uden at udløse gengivelser? Brug
useRef
. - Har du brug for at spore den tidligere værdi af en prop? Brug
useRef
.
Ud over DOM-manipulation: Avancerede anvendelsestilfælde for Refs
Selvom adgang til og manipulation af DOM-elementer er et primært anvendelsestilfælde for Refs, tilbyder de muligheder ud over denne kernefunktionalitet. Lad os udforske nogle avancerede scenarier, hvor Refs kan være særligt nyttige.
1. Få adgang til underkomponentmetoder
Refs kan bruges til at få adgang til metoder, der er defineret i underkomponenter. Dette giver en overordnet komponent mulighed for at udløse handlinger eller hente data direkte fra sine underordnede. Denne tilgang er især nyttig, når du har brug for finkornet kontrol over underkomponenter.
class ParentComponent extends React.Component {
constructor(props) {
super(props);
this.childRef = React.createRef();
}
handleClick = () => {
// Call a method on the child component
this.childRef.current.doSomething();
};
render() {
return (
<div>
<ChildComponent ref={this.childRef} />
<button onClick={this.handleClick}>Trigger Child Action</button>
</div>
);
}
}
class ChildComponent extends React.Component {
doSomething = () => {
console.log('Child component action triggered!');
};
render() {
return <div>This is a child component.</div>;
}
}
I dette eksempel bruger ParentComponent
en Ref til at få adgang til ChildComponent
og kalde dens doSomething
-metode.
2. Styring af fokus og markering
Refs er uvurderlige til at styre fokus og markering i inputfelter og andre interaktive elementer. Dette er afgørende for at skabe tilgængelige og brugervenlige grænseflader.
import React, { useRef, useEffect } from 'react';
function FocusOnMount() {
const inputRef = useRef(null);
useEffect(() => {
if (inputRef.current) {
inputRef.current.focus();
inputRef.current.select(); // Select the text in the input
}
}, []);
return <input type="text" ref={inputRef} defaultValue="Initial text" />;
}
Dette eksempel fokuserer input og vælger dets tekst, så snart komponenten monteres.
3. Animering af elementer
Refs kan bruges i forbindelse med animationsbiblioteker (som GreenSock eller Framer Motion) til direkte at manipulere DOM og skabe komplekse animationer. Dette giver mulighed for finkornet kontrol over animationssekvenser.
Eksempel ved hjælp af almindelig JavaScript for enkelhedens skyld:
import React, { useRef, useEffect } from 'react';
function AnimatedBox() {
const boxRef = useRef(null);
useEffect(() => {
const box = boxRef.current;
if (box) {
// Simple animation: move the box to the right
box.animate(
[
{ transform: 'translateX(0)' },
{ transform: 'translateX(100px)' },
],
{
duration: 1000, // 1 second
iterations: Infinity, // Repeat forever
direction: 'alternate',
}
);
}
}, []);
return <div ref={boxRef} style={{ width: '100px', height: '100px', backgroundColor: 'lightblue' }}></div>;
}
Dette eksempel bruger Web Animations API til at animere en simpel boks, der bevæger den frem og tilbage vandret.
Best Practices for brug af React Refs i globale applikationer
Når du udvikler React-applikationer til et globalt publikum, er det vigtigt at overveje, hvordan Refs interagerer med internationalisering (i18n) og lokalisering (l10n). Her er nogle best practices:
1. Tilgængelighed (A11y)
Sørg for, at din brug af Refs ikke har en negativ indvirkning på tilgængeligheden. Når du f.eks. programmatisk fokuserer elementer, skal du overveje brugerens fokusrækkefølge, og om fokusændringen er passende for skærmlæsere og tastaturbrugere.
import React, { useRef, useEffect } from 'react';
function AccessibleFocus() {
const buttonRef = useRef(null);
useEffect(() => {
const button = buttonRef.current;
if (button) {
// Only focus if the button is not already focused by the user
if (document.activeElement !== button) {
button.focus();
}
}
}, []);
return <button ref={buttonRef}>Click Me</button>;
}
2. Internationaliserede inputfelter
Når du arbejder med inputfelter, skal du være opmærksom på forskellige inputmetoder og tegnsæt, der bruges på forskellige sprog. Sørg for, at dine Ref-baserede manipulationer (f.eks. markering, markørposition) fungerer korrekt på tværs af forskellige inputtyper og lokaliteter. Test dine komponenter grundigt med forskellige sprog og inputmetoder.
3. Højre-til-venstre-layouts (RTL)
Hvis din applikation understøtter RTL-sprog (f.eks. arabisk, hebraisk), skal du sikre dig, at dine DOM-manipulationer ved hjælp af Refs tager højde for det omvendte layout. Når du f.eks. animerer elementer, skal du overveje at vende animationsretningen for RTL-sprog.
4. Ydeevneovervejelser
Selvom Refs giver en effektiv måde at interagere med DOM på, kan overforbrug føre til ydeevneproblemer. Direkte DOM-manipulation omgår Reacts virtuelle DOM og afstemningsproces, hvilket potentielt kan føre til uoverensstemmelser og langsommere opdateringer. Brug Refs med omtanke og kun når det er nødvendigt.
Konklusion
React Refs, specifikt useRef
og createRef
, er vigtige værktøjer for React-udviklere. Det er afgørende at forstå nuancerne i hver tilgang, og hvornår man effektivt kan anvende dem, for at opbygge robuste og højtydende applikationer. createRef
er fortsat standarden for styring af Refs i klassekomponenter, hvilket sikrer, at hver instans har sin unikke Ref. useRef
, med sin vedvarende karakter på tværs af gengivelser, er ideel til funktionelle komponenter og tilbyder en måde at administrere DOM-elementer og fastholde værdier uden at udløse unødvendige gengivelser. Ved at udnytte disse værktøjer klogt kan du forbedre funktionaliteten og brugeroplevelsen af dine React-applikationer og imødekomme et globalt publikum med tilgængelige og højtydende grænseflader.
Efterhånden som React fortsætter med at udvikle sig, vil mestring af disse grundlæggende koncepter give dig mulighed for at skabe innovative og brugervenlige weboplevelser, der overskrider geografiske og kulturelle grænser. Husk at prioritere tilgængelighed, internationalisering og ydeevne for at levere virkelig globale applikationer.