Kompleksowy przewodnik po React Refs, koncentrujący się na useRef i createRef. Dowiedz się, jak i kiedy używać każdego z nich do efektywnego zarządzania komponentami i dostępu do DOM w globalnych aplikacjach.
React Refs: Demistyfikacja useRef vs. createRef
W dynamicznym świecie tworzenia aplikacji w React, efektywne zarządzanie stanem komponentów i interakcja z Document Object Model (DOM) są kluczowe. React Refs zapewniają mechanizm do bezpośredniego dostępu i manipulowania elementami DOM lub komponentami React. Dwie podstawowe metody tworzenia Refs to useRef
i createRef
. Chociaż obie służą do tworzenia Refs, różnią się implementacją i przypadkami użycia. Ten przewodnik ma na celu demistyfikację tych dwóch podejść, zapewniając jasność co do tego, kiedy i jak skutecznie wykorzystywać każdy z nich w projektach React, zwłaszcza podczas tworzenia aplikacji dla globalnej publiczności.
Zrozumienie React Refs
Ref (skrót od reference, czyli odniesienie) to funkcja React, która pozwala na bezpośredni dostęp do węzła DOM lub komponentu React. Jest to szczególnie przydatne, gdy potrzebujesz:
- Bezpośrednio manipulować elementem DOM, takim jak ustawianie fokusu na polu wprowadzania.
- Uzyskać dostęp do metod lub właściwości komponentu potomnego.
- Zarządzać wartościami, które utrzymują się między renderowaniami, nie powodując ponownych renderowań (podobnie do zmiennych instancji w komponentach klasowych).
Chociaż React promuje deklaratywne podejście, gdzie interfejs użytkownika jest zarządzany przez stan i propsy, istnieją sytuacje, w których konieczna jest bezpośrednia manipulacja. Refs zapewniają sposób na połączenie deklaratywności React z imperatywnymi operacjami DOM.
createRef
: Podejście z Komponentami Klasowymi
createRef
to metoda dostarczana przez React. Jest ona głównie używana w komponentach klasowych do tworzenia Refs. Za każdym razem, gdy instancja komponentu klasowego jest tworzona, createRef
tworzy nowy obiekt Ref. Zapewnia to, że każda instancja komponentu posiada własny, unikalny Ref.
Składnia i Użycie
Aby użyć createRef
, najpierw deklarujesz Ref w swoim komponencie klasowym, zazwyczaj w konstruktorze. Następnie przypisujesz Ref do elementu DOM lub komponentu za pomocą atrybutu ref
.
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
componentDidMount() {
// Dostęp do elementu DOM po zamontowaniu komponentu
this.myRef.current.focus();
}
render() {
return ;
}
}
W tym przykładzie this.myRef
jest tworzony za pomocą React.createRef()
. Następnie jest przypisywany do atrybutu ref
elementu input. Po zamontowaniu komponentu (w componentDidMount
), możesz uzyskać dostęp do faktycznego węzła DOM za pomocą this.myRef.current
i wykonać na nim operacje (w tym przypadku, ustawić fokus na polu wprowadzania).
Przykład: Ustawianie Fokusu na Polu Wprowadzania
Rozważmy scenariusz, w którym chcesz automatycznie ustawić fokus na polu wprowadzania po zamontowaniu komponentu. Jest to częste zastosowanie Refs, szczególnie w formularzach lub interaktywnych elementach.
class FocusInput extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
componentDidMount() {
this.inputRef.current.focus();
}
render() {
return (
);
}
}
W tym przykładzie FocusInput
ustawia fokus na polu wprowadzania natychmiast po zamontowaniu. Może to poprawić doświadczenie użytkownika, kierując uwagę użytkownika na element wprowadzania zaraz po wyrenderowaniu komponentu.
Ważne Uwagi dotyczące createRef
- Tylko w Komponentach Klasowych:
createRef
jest przeznaczony do użytku w komponentach klasowych. Chociaż technicznie może działać w komponentach funkcyjnych, nie jest to zamierzone zastosowanie i może prowadzić do nieoczekiwanych zachowań. - Nowa Instancja Ref dla Każdej Instancji: Każda instancja komponentu klasowego otrzymuje własny
createRef
. Jest to ważne dla utrzymania izolacji między instancjami komponentów.
useRef
: Hook dla Komponentów Funkcyjnych
useRef
to Hook, który został wprowadzony w React 16.8. Zapewnia sposób na tworzenie mutowalnych obiektów Ref w komponentach funkcyjnych. W przeciwieństwie do createRef
, useRef
zwraca ten sam obiekt Ref za każdym razem, gdy komponent się renderuje. To czyni go idealnym do utrzymywania wartości między renderowaniami bez wywoływania ponownych renderowań.
Składnia i Użycie
Użycie useRef
jest proste. Wywołujesz Hook useRef
, przekazując początkową wartość. Hook zwraca obiekt z właściwością .current
, którą następnie możesz wykorzystać do dostępu i modyfikacji wartości.
import React, { useRef, useEffect } from 'react';
function MyFunctionalComponent() {
const myRef = useRef(null);
useEffect(() => {
// Dostęp do elementu DOM po zamontowaniu komponentu
if (myRef.current) {
myRef.current.focus();
}
}, []);
return ;
}
W tym przykładzie useRef(null)
tworzy Ref z początkową wartością null
. Hook useEffect
jest używany do uzyskania dostępu do elementu DOM po zamontowaniu komponentu. Właściwość myRef.current
przechowuje odniesienie do elementu input, umożliwiając ustawienie na nim fokusu.
Przykład: Śledzenie Poprzednich Wartości Prop
Jednym z potężnych zastosowań useRef
jest śledzenie poprzedniej wartości prop. Ponieważ zmiany w Refs nie wywołują ponownych renderowań, możesz ich używać do przechowywania wartości, które chcesz utrzymać między renderowaniami, nie wpływając na interfejs użytkownika.
import React, { useRef, useEffect } from 'react';
function PreviousValueComponent({ value }) {
const previousValue = useRef();
useEffect(() => {
previousValue.current = value;
}, [value]);
return (
Aktualna Wartość: {value}
Poprzednia Wartość: {previousValue.current}
);
}
W tym przykładzie previousValue.current
przechowuje poprzednią wartość prop value
. Hook useEffect
aktualizuje Ref za każdym razem, gdy prop value
się zmienia. Pozwala to na porównanie bieżącej i poprzedniej wartości, co może być przydatne do wykrywania zmian lub implementacji animacji.
Ważne Uwagi dotyczące useRef
- Tylko w Komponentach Funkcyjnych:
useRef
jest Hookiem i może być używany tylko w komponentach funkcyjnych lub niestandardowych Hookach. - Utrzymuje się Między Renderowaniami: Hook
useRef
zwraca ten sam obiekt Ref przy każdym renderowaniu. Jest to kluczowe dla jego możliwości utrzymywania wartości bez wywoływania ponownych renderowań. - Mutowalna Właściwość
.current
: Możesz bezpośrednio modyfikować właściwość.current
obiektu Ref. - Wartość Początkowa: Możesz podać wartość początkową do
useRef
. Ta wartość zostanie przypisana do właściwości.current
podczas pierwszego renderowania komponentu. - Brak Ponownych Renderowań: Modyfikacja właściwości
.current
Ref nie powoduje ponownego renderowania komponentu.
useRef
vs. createRef
: Szczegółowe Porównanie
Teraz, gdy zbadaliśmy oba useRef
i createRef
indywidualnie, porównajmy je obok siebie, aby podkreślić ich kluczowe różnice i kiedy wybrać jedno zamiast drugiego.
Cecha | useRef |
createRef |
---|---|---|
Typ Komponentu | Komponenty Funkcyjne | Komponenty Klasowe |
Hook czy Metoda | Hook | Metoda |
Instancja Ref | Zwraca ten sam obiekt Ref przy każdym renderowaniu | Tworzy nowy obiekt Ref dla każdej instancji komponentu |
Przypadki Użycia |
|
|
Wybór Właściwego Ref: Przewodnik Decyzyjny
Oto prosty przewodnik, który pomoże Ci wybrać między useRef
a createRef
:
- Czy pracujesz z komponentem funkcyjnym? Użyj
useRef
. - Czy pracujesz z komponentem klasowym? Użyj
createRef
. - Czy potrzebujesz utrzymać wartość między renderowaniami bez wywoływania ponownych renderowań? Użyj
useRef
. - Czy potrzebujesz śledzić poprzednią wartość prop? Użyj
useRef
.
Poza Manipulacją DOM: Zaawansowane Zastosowania Refs
Chociaż dostęp i manipulacja elementami DOM są głównymi zastosowaniami Refs, oferują one możliwości wykraczające poza tę podstawową funkcjonalność. Przyjrzyjmy się kilku zaawansowanym scenariuszom, w których Refs mogą być szczególnie przydatne.
1. Dostęp do Metod Komponentów Potomnych
Refs mogą być używane do uzyskiwania dostępu do metod zdefiniowanych w komponentach potomnych. Pozwala to komponentowi nadrzędnemu na bezpośrednie wywoływanie akcji lub pobieranie danych od swoich potomków. To podejście jest szczególnie przydatne, gdy potrzebujesz szczegółowej kontroli nad komponentami potomnymi.
class ParentComponent extends React.Component {
constructor(props) {
super(props);
this.childRef = React.createRef();
}
handleClick = () => {
// Wywołaj metodę na komponencie potomnym
this.childRef.current.doSomething();
};
render() {
return (
);
}
}
class ChildComponent extends React.Component {
doSomething = () => {
console.log('Akcja komponentu potomnego wyzwolona!');
};
render() {
return To jest komponent potomny.;
}
}
W tym przykładzie ParentComponent
używa Ref do uzyskania dostępu do ChildComponent
i wywołania jego metody doSomething
.
2. Zarządzanie Fokusem i Zaznaczeniem
Refs są nieocenione w zarządzaniu fokusem i zaznaczeniem w polach wprowadzania i innych interaktywnych elementach. Jest to kluczowe dla tworzenia dostępnych i przyjaznych dla użytkownika interfejsów.
import React, { useRef, useEffect } from 'react';
function FocusOnMount() {
const inputRef = useRef(null);
useEffect(() => {
if (inputRef.current) {
inputRef.current.focus();
inputRef.current.select(); // Zaznacz tekst w polu wprowadzania
}
}, []);
return ;
}
Ten przykład ustawia fokus na polu wprowadzania i zaznacza jego tekst zaraz po zamontowaniu komponentu.
3. Animowanie Elementów
Refs mogą być używane w połączeniu z bibliotekami animacji (takimi jak GreenSock czy Framer Motion) do bezpośredniej manipulacji DOM i tworzenia złożonych animacji. Pozwala to na szczegółową kontrolę nad sekwencjami animacji.
Przykład z użyciem czystego JavaScript dla uproszczenia:
import React, { useRef, useEffect } from 'react';
function AnimatedBox() {
const boxRef = useRef(null);
useEffect(() => {
const box = boxRef.current;
if (box) {
// Prosta animacja: przesunięcie pudełka w prawo
box.animate(
[
{ transform: 'translateX(0)' },
{ transform: 'translateX(100px)' },
],
{
duration: 1000, // 1 sekunda
iterations: Infinity, // Powtarzaj w nieskończoność
direction: 'alternate',
}
);
}
}, []);
return ;
}
Ten przykład używa Web Animations API do animowania prostego pudełka, przesuwając je tam i z powrotem poziomo.
Dobre Praktyki Używania React Refs w Aplikacjach Globalnych
Podczas tworzenia aplikacji React dla globalnej publiczności, ważne jest, aby rozważyć, jak Refs wchodzą w interakcję z internacjonalizacją (i18n) i lokalizacją (l10n). Oto kilka dobrych praktyk:
1. Dostępność (A11y)
Upewnij się, że Twoje użycie Refs nie wpływa negatywnie na dostępność. Na przykład, podczas programowego ustawiania fokusu na elementach, rozważ kolejność fokusu użytkownika i czy zmiana fokusu jest odpowiednia dla czytników ekranu i użytkowników klawiatury.
import React, { useRef, useEffect } from 'react';
function AccessibleFocus() {
const buttonRef = useRef(null);
useEffect(() => {
const button = buttonRef.current;
if (button) {
// Ustaw fokus tylko wtedy, gdy przycisk nie ma już fokusu ustawionego przez użytkownika
if (document.activeElement !== button) {
button.focus();
}
}
}, []);
return ;
}
2. Zlokalizowane Pola Wprowadzania
Pracując z polami wprowadzania, zwracaj uwagę na różne metody wprowadzania i zestawy znaków używane w różnych językach. Upewnij się, że manipulacje oparte na Refs (np. zaznaczenie, pozycja kursora) działają poprawnie dla różnych typów wprowadzania i lokalizacji. Dokładnie testuj swoje komponenty z różnymi językami i metodami wprowadzania.
3. Układy Prawo-do-Lewo (RTL)
Jeśli Twoja aplikacja obsługuje języki RTL (np. arabski, hebrajski), upewnij się, że Twoje manipulacje DOM za pomocą Refs uwzględniają odwrócony układ. Na przykład, podczas animowania elementów, rozważ odwrócenie kierunku animacji dla języków RTL.
4. Względy Wydajnościowe
Chociaż Refs zapewniają potężny sposób interakcji z DOM, nadmierne ich użycie może prowadzić do problemów z wydajnością. Bezpośrednia manipulacja DOM omija wirtualny DOM React i proces rekonsyliacji, potencjalnie prowadząc do niespójności i wolniejszych aktualizacji. Używaj Refs rozważnie i tylko wtedy, gdy jest to konieczne.
Podsumowanie
React Refs, w szczególności useRef
i createRef
, są niezbędnymi narzędziami dla deweloperów React. Zrozumienie niuansów każdego podejścia i tego, kiedy je skutecznie stosować, jest kluczowe dla tworzenia solidnych i wydajnych aplikacji. createRef
pozostaje standardem do zarządzania Refs w komponentach klasowych, zapewniając, że każda instancja posiada swój unikalny Ref. useRef
, dzięki swojej trwałości między renderowaniami, jest idealny dla komponentów funkcyjnych, oferując sposób na zarządzanie elementami DOM i utrzymywanie wartości bez wywoływania niepotrzebnych ponownych renderowań. Mądrze wykorzystując te narzędzia, możesz poprawić funkcjonalność i doświadczenie użytkownika swoich aplikacji React, obsługując globalną publiczność za pomocą dostępnych i wydajnych interfejsów.
W miarę ewolucji React, opanowanie tych fundamentalnych koncepcji pozwoli Ci tworzyć innowacyjne i przyjazne dla użytkownika doświadczenia internetowe, które przekraczają granice geograficzne i kulturowe. Pamiętaj, aby priorytetowo traktować dostępność, internacjonalizację i wydajność, aby dostarczać prawdziwie globalne aplikacje.