Mestre React refs for å direkte manipulere DOM, håndtere fokus, integrere tredjepartsbiblioteker og optimalisere UI-ytelse. En omfattende guide for moderne React-utvikling.
React Ref-mønstre: Teknikker for DOM-manipulering for dynamiske brukergrensesnitt
React, et kraftig JavaScript-bibliotek for å bygge brukergrensesnitt, oppfordrer ofte til en deklarativ tilnærming til UI-utvikling. Noen ganger blir imidlertid direkte manipulering av Document Object Model (DOM) nødvendig. Det er her React refs kommer inn i bildet. Refs gir en måte å få tilgang til DOM-noder eller React-elementer som er opprettet i render-metoden. Denne omfattende guiden utforsker ulike React ref-mønstre og teknikker for effektivt å manipulere DOM, håndtere fokus, integrere med tredjepartsbiblioteker og optimalisere UI-ytelse. Vi vil dykke ned i praktiske eksempler og beste praksis som passer for et globalt publikum av React-utviklere.
Forståelse av React Refs
I sin kjerne er en ref et vanlig JavaScript-objekt med en current
-egenskap. Denne egenskapen er muterbar, noe som lar deg lagre hvilken som helst verdi, inkludert en DOM-node eller en instans av en React-komponent. React tilbyr to primære måter å lage refs på: React.createRef()
(klassekomponenter) og useRef()
-hooken (funksjonelle komponenter).
React.createRef() (klassekomponenter)
React.createRef()
oppretter et ref-objekt som tildeles en egenskap på en klassekomponents instans. Denne ref-en vedvarer gjennom hele komponentens livssyklus.
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
componentDidMount() {
// Få tilgang til DOM-noden etter at komponenten monteres
console.log(this.myRef.current); // DOM-node eller null
}
render() {
return Hello, world!;
}
}
useRef() (funksjonelle komponenter)
useRef()
-hooken oppretter et muterbart ref-objekt hvis .current
-egenskap blir initialisert med det gitte argumentet (initialValue
). Det returnerte ref-objektet vil vedvare gjennom hele komponentens levetid.
import React, { useRef, useEffect } from 'react';
function MyFunctionalComponent() {
const myRef = useRef(null);
useEffect(() => {
// Få tilgang til DOM-noden etter at komponenten monteres
console.log(myRef.current); // DOM-node eller null
}, []); // Tomt avhengighetsarray sikrer at dette kun kjøres én gang ved montering
return Hello, world!;
}
Vanlige bruksområder for React Refs
Refs er utrolig allsidige og finner anvendelse i ulike scenarier innen React-utvikling.
1. Tilgang til og manipulering av DOM-noder
Det vanligste bruksområdet for refs er å få direkte tilgang til og manipulere DOM-noder. Dette er nyttig for oppgaver som å fokusere på et input-felt, rulle til et element eller måle dimensjonene dets.
import React, { useRef, useEffect } from 'react';
function FocusInput() {
const inputRef = useRef(null);
useEffect(() => {
// Fokuser på input-feltet etter at komponenten monteres
if (inputRef.current) {
inputRef.current.focus();
}
}, []);
return ;
}
Eksempel: Tenk deg at du bygger et flertrinnsskjema. Når en bruker fullfører et felt, vil du kanskje automatisk fokusere på neste input. Refs gjør dette sømløst.
2. Håndtere fokus, tekstmarkering og medieavspilling
Refs er essensielle for finkornet kontroll over fokus, tekstmarkering i elementer og håndtering av medieavspilling (f.eks. video eller lyd).
import React, { useRef, useEffect } from 'react';
function VideoPlayer() {
const videoRef = useRef(null);
const playVideo = () => {
if (videoRef.current) {
videoRef.current.play();
}
};
const pauseVideo = () => {
if (videoRef.current) {
videoRef.current.pause();
}
};
return (
);
}
Hensyn til tilgjengelighet: Når du bruker refs for å håndtere fokus, sørg for riktig fokusstyring for å opprettholde tilgjengeligheten for brukere som er avhengige av tastaturnavigasjon eller hjelpeteknologier. For eksempel, etter at en modal åpnes, sett fokus umiddelbart til det første fokuserbare elementet i modalen.
3. Integrering med tredjepartsbiblioteker
Mange tredjeparts JavaScript-biblioteker manipulerer DOM direkte. Refs gir en bro mellom Reacts deklarative modell og disse imperative bibliotekene.
import React, { useRef, useEffect } from 'react';
import Chart from 'chart.js/auto'; // Eksempel: Bruker Chart.js
function ChartComponent() {
const chartRef = useRef(null);
useEffect(() => {
if (chartRef.current) {
const ctx = chartRef.current.getContext('2d');
new Chart(ctx, {
type: 'bar',
data: {
labels: ['Rød', 'Blå', 'Gul', 'Grønn', 'Lilla', 'Oransje'],
datasets: [{
label: '# av stemmer',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
}
}, []);
return ;
}
Merknad om internasjonalisering: Når du integrerer tredjepartsbiblioteker som håndterer datoer, tall eller valutaer, sørg for at de er riktig konfigurert for å støtte brukerens locale (språk- og regionsinnstillinger). Mange biblioteker tilbyr alternativer for å spesifisere ønsket locale. For eksempel bør datoforrmateringsbiblioteker initialiseres med brukerens språk og region for å vise datoer i riktig format (f.eks. MM/DD/YYYY vs. DD/MM/YYYY).
4. Utløse imperative animasjoner
Selv om React-biblioteker som Framer Motion og React Transition Group foretrekkes for de fleste animasjonsbehov, kan refs brukes for imperative animasjoner når mer finkornet kontroll er nødvendig.
import React, { useRef, useEffect } from 'react';
function FadeIn() {
const elementRef = useRef(null);
useEffect(() => {
const element = elementRef.current;
if (element) {
element.style.opacity = 0; // Initielt skjult
let opacity = 0;
const intervalId = setInterval(() => {
opacity += 0.05;
element.style.opacity = opacity;
if (opacity >= 1) {
clearInterval(intervalId);
}
}, 20); // Juster intervallet for hastighet
return () => clearInterval(intervalId); // Rydd opp ved avmontering
}
}, []);
return Fade inn!;
}
5. Måle elementdimensjoner
Refs lar deg nøyaktig måle dimensjonene (bredde, høyde) til elementer i DOM. Dette er nyttig for responsive layouter, dynamisk posisjonering og for å lage egendefinerte visuelle effekter.
import React, { useRef, useEffect, useState } from 'react';
function MeasureElement() {
const elementRef = useRef(null);
const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
useEffect(() => {
const element = elementRef.current;
if (element) {
const width = element.offsetWidth;
const height = element.offsetHeight;
setDimensions({ width, height });
}
}, []);
return (
Mål dette elementet
Bredde: {dimensions.width}px
Høyde: {dimensions.height}px
);
}
Avanserte Ref-mønstre
Utover den grunnleggende bruken av createRef
og useRef
, finnes det flere avanserte mønstre som utnytter refs for mer komplekse scenarier.
1. Callback Refs
Callback refs gir en mer fleksibel måte å få tilgang til DOM-noder på. I stedet for å tildele et ref-objekt, tildeler du en funksjon til ref
-attributtet. React vil kalle denne funksjonen med DOM-noden når komponenten monteres, og med null
når den avmonteres.
import React, { useState } from 'react';
function CallbackRefExample() {
const [element, setElement] = useState(null);
const setRef = (node) => {
setElement(node);
};
return (
Ref-en til dette elementet håndteres av en callback.
{element && Element: {element.tagName}
}
);
}
Callback refs er spesielt nyttige når du trenger å utføre tilleggshandlinger når ref-en blir satt eller fjernet.
2. Videresende Refs (forwardRef)
React.forwardRef
er en teknikk som lar en komponent motta en ref sendt fra sin foreldrekomponent. Dette er nyttig når du vil eksponere en DOM-node fra en barnekomponent til dens forelder.
import React, { forwardRef } from 'react';
const MyInput = forwardRef((props, ref) => {
return ;
});
function ParentComponent() {
const inputRef = React.useRef(null);
const focusInput = () => {
if (inputRef.current) {
inputRef.current.focus();
}
};
return (
);
}
I dette eksempelet videresender MyInput
ref-en til det underliggende input-elementet, noe som lar ParentComponent
få direkte tilgang til og manipulere input-elementet.
3. Eksponere komponentmetoder med Refs
Refs kan også brukes til å eksponere metoder fra en barnekomponent til dens forelder. Dette er nyttig for å lage gjenbrukbare komponenter med imperative API-er.
import React, { useRef, useImperativeHandle, forwardRef } from 'react';
const FancyInput = forwardRef((props, ref) => {
const inputRef = useRef(null);
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
},
getValue: () => {
return inputRef.current.value;
}
}));
return ;
});
function ParentComponent() {
const fancyInputRef = useRef(null);
const handleFocus = () => {
fancyInputRef.current.focus();
};
const handleGetValue = () => {
alert(fancyInputRef.current.getValue());
};
return (
);
}
useImperativeHandle
-hooken lar deg tilpasse instansverdien som eksponeres for foreldrekomponenter når du bruker forwardRef
. Dette gir kontrollert tilgang til barnets metoder.
Beste praksis for bruk av React Refs
Selv om refs gir kraftige muligheter, er det avgjørende å bruke dem med omhu og følge beste praksis.
- Unngå overdreven DOM-manipulering: Reacts deklarative tilnærming er generelt mer effektiv. Bruk bare refs når det er nødvendig for oppgaver som ikke enkelt kan oppnås gjennom Reacts state-håndtering.
- Bruk refs med måte: Overdreven bruk av refs kan føre til kode som er vanskeligere å vedlikeholde og resonnere om.
- Vær oppmerksom på komponentens livssyklus: Sørg for at du kun får tilgang til
.current
-egenskapen til en ref etter at komponenten er montert (f.eks. icomponentDidMount
elleruseEffect
). Tilgang før dette kan resultere inull
-verdier. - Rydd opp i refs: Når du bruker callback refs, sørg for at du setter ref-en til
null
når komponenten avmonteres for å forhindre minnelekkasjer. - Vurder alternativer: Før du tyr til refs, utforsk om Reacts state-håndtering eller kontrollerte komponenter kan oppnå ønsket atferd.
- Tilgjengelighet: Når du manipulerer fokus, sørg for at applikasjonen forblir tilgjengelig for brukere med nedsatt funksjonsevne.
Globale hensyn ved bruk av Ref
Når du bygger applikasjoner for et globalt publikum, bør du vurdere følgende aspekter ved bruk av refs:
- Høyre-til-venstre (RTL) layouter: Når du manipulerer DOM-elementer relatert til layout (f.eks. rulling), sørg for at koden din håndterer RTL-layouter korrekt for språk som arabisk og hebraisk. Bruk egenskaper som
scrollLeft
ogscrollWidth
med forsiktighet og normaliser dem potensielt basert på layoutens retning. - Input Method Editors (IME-er): Vær klar over at brukere i noen regioner kan bruke IME-er for å skrive inn tekst. Når du håndterer fokus eller tekstmarkering, sørg for at koden din samhandler korrekt med IME-er og ikke forstyrrer brukerens input.
- Font-innlasting: Hvis du måler elementdimensjoner før fonter er fullstendig lastet, kan de første målingene være feil. Bruk teknikker for å sikre at fonter er lastet før du stoler på disse målingene (f.eks. ved å bruke
document.fonts.ready
). Ulike skriftsystemer (f.eks. latinsk, kyrillisk, CJK) har vidt forskjellige fontstørrelser og metrikker. - Brukerpreferanser: Vurder brukerpreferanser for animasjoner og overganger. Noen brukere foretrekker redusert bevegelse. Respekter disse preferansene når du bruker refs for å utløse animasjoner. Bruk CSS-mediespørringen `prefers-reduced-motion` for å oppdage brukerpreferanser.
Konklusjon
React refs er et kraftig verktøy for å direkte manipulere DOM, håndtere fokus, integrere med tredjepartsbiblioteker og optimalisere UI-ytelse. Ved å forstå de forskjellige ref-mønstrene og følge beste praksis, kan du utnytte refs effektivt samtidig som du opprettholder fordelene med Reacts deklarative tilnærming. Husk å vurdere globale tilgjengelighets- og internasjonaliseringsaspekter for å skape inkluderende og brukervennlige applikasjoner for et mangfoldig publikum. Med nøye planlegging og implementering kan React refs betydelig forbedre funksjonaliteten og responsiviteten til React-applikasjonene dine.