Български

Подробно ръководство, изследващо React Refs, с фокус върху useRef и createRef. Научете как и кога да използвате всяко от тях за ефективно управление на компоненти и достъп до DOM в глобални приложения.

React Refs: Демистификация на useRef срещу createRef

В динамичния свят на React разработката, ефективното управление на състоянието на компонентите и взаимодействието с Document Object Model (DOM) е от решаващо значение. React Refs предоставят механизъм за директен достъп и манипулация на DOM елементи или React компоненти. Два основни метода за създаване на Refs са useRef и createRef. Въпреки че и двата служат за създаване на Refs, те се различават по своята имплементация и случаи на употреба. Това ръководство има за цел да демистифицира тези два подхода, като предостави яснота кога и как да използвате всеки от тях ефективно във вашите React проекти, особено при разработка за глобална аудитория.

Разбиране на React Refs

Ref (съкратено от reference - референция) е функция на React, която ви позволява да получите директен достъп до DOM възел или React компонент. Това е особено полезно, когато трябва да:

Въпреки че React насърчава декларативен подход, при който потребителският интерфейс се управлява чрез състояние и props, има ситуации, в които е необходима директна манипулация. Refs предоставят начин за преодоляване на пропастта между декларативната природа на React и императивните DOM операции.

createRef: Подходът при класовите компоненти

createRef е метод, предоставен от React. Той се използва предимно в класови компоненти за създаване на Refs. Всеки път, когато се инстанциира класов компонент, createRef създава нов Ref обект. Това гарантира, че всяка инстанция на компонента има своя собствена уникална референция.

Синтаксис и употреба

За да използвате createRef, първо декларирате Ref във вашия класов компонент, обикновено в конструктора. След това прикачвате референцията към DOM елемент или компонент, използвайки атрибута ref.


class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }

  componentDidMount() {
    // Достъп до DOM елемента, след като компонентът се монтира
    this.myRef.current.focus();
  }

  render() {
    return ;
  }
}

В този пример this.myRef се създава с помощта на React.createRef(). След това се присвоява на атрибута ref на input елемента. След като компонентът се монтира (в componentDidMount), можете да получите достъп до реалния DOM възел, използвайки this.myRef.current и да извършвате операции върху него (в този случай, фокусиране на полето за въвеждане).

Пример: Фокусиране на поле за въвеждане

Нека разгледаме сценарий, при който искате автоматично да фокусирате поле за въвеждане, когато компонентът се монтира. Това е често срещан случай на употреба на Refs, особено във форми или интерактивни елементи.


class FocusInput extends React.Component {
  constructor(props) {
    super(props);
    this.inputRef = React.createRef();
  }

  componentDidMount() {
    this.inputRef.current.focus();
  }

  render() {
    return (
      
); } }

В този пример, FocusInput фокусира полето за въвеждане веднага след монтиране. Това може да подобри потребителското изживяване, като насочи вниманието на потребителя към input елемента веднага щом компонентът се рендира.

Важни съображения при createRef

useRef: Хукът за функционални компоненти

useRef е хук (Hook), който беше въведен в React 16.8. Той предоставя начин за създаване на променливи Ref обекти в рамките на функционални компоненти. За разлика от createRef, useRef връща един и същ Ref обект при всяко рендиране на компонента. Това го прави идеален за запазване на стойности между рендърите, без да задейства повторно рендиране.

Синтаксис и употреба

Използването на useRef е лесно. Викате хука useRef, като предавате начална стойност. Хукът връща обект със свойство .current, което след това можете да използвате за достъп и промяна на стойността.


import React, { useRef, useEffect } from 'react';

function MyFunctionalComponent() {
  const myRef = useRef(null);

  useEffect(() => {
    // Достъп до DOM елемента, след като компонентът се монтира
    if (myRef.current) {
      myRef.current.focus();
    }
  }, []);

  return ;
}

В този пример useRef(null) създава Ref с начална стойност null. Хукът useEffect се използва за достъп до DOM елемента след монтирането на компонента. Свойството myRef.current съдържа референцията към input елемента, което ви позволява да го фокусирате.

Пример: Проследяване на предишни стойности на props

Един мощен случай на употреба на useRef е проследяването на предишната стойност на prop. Тъй като промените в Refs не задействат повторно рендиране, можете да ги използвате за съхраняване на стойности, които искате да се запазят между рендърите, без да засягат потребителския интерфейс.


import React, { useRef, useEffect } from 'react';

function PreviousValueComponent({ value }) {
  const previousValue = useRef();

  useEffect(() => {
    previousValue.current = value;
  }, [value]);

  return (
    

Текуща стойност: {value}

Предишна стойност: {previousValue.current}

); }

В този пример previousValue.current съхранява предишната стойност на prop-а value. Хукът useEffect актуализира референцията всеки път, когато prop-ът value се промени. Това ви позволява да сравнявате текущите и предишните стойности, което може да бъде полезно за откриване на промени или прилагане на анимации.

Важни съображения при useRef

useRef срещу createRef: Подробно сравнение

След като разгледахме поотделно както useRef, така и createRef, нека ги сравним, за да подчертаем ключовите им разлики и кога да изберем едното пред другото.

Характеристика useRef createRef
Тип на компонента Функционални компоненти Класови компоненти
Хук или метод Хук Метод
Инстанция на Ref Връща един и същ Ref обект при всяко рендиране Създава нов Ref обект при всяка инстанция на компонента
Случаи на употреба
  • Достъп до DOM елементи
  • Запазване на стойности между рендърите без задействане на повторно рендиране
  • Проследяване на предишни стойности на props
  • Съхраняване на променливи стойности, които не предизвикват повторно рендиране
  • Достъп до DOM елементи
  • Достъп до методи на дъщерни компоненти

Избор на правилния Ref: Ръководство за вземане на решения

Ето едно просто ръководство, което ще ви помогне да изберете между useRef и createRef:

Отвъд DOM манипулацията: Разширени случаи на употреба за Refs

Въпреки че достъпът и манипулирането на DOM елементи е основен случай на употреба за Refs, те предлагат възможности извън тази основна функционалност. Нека разгледаме някои напреднали сценарии, в които Refs могат да бъдат особено полезни.

1. Достъп до методи на дъщерни компоненти

Refs могат да се използват за достъп до методи, дефинирани в дъщерни компоненти. Това позволява на родителски компонент да задейства действия или да извлича данни директно от своите деца. Този подход е особено полезен, когато се нуждаете от фин контрол върху дъщерните компоненти.


class ParentComponent extends React.Component {
  constructor(props) {
    super(props);
    this.childRef = React.createRef();
  }

  handleClick = () => {
    // Извикване на метод на дъщерния компонент
    this.childRef.current.doSomething();
  };

  render() {
    return (
      
); } } class ChildComponent extends React.Component { doSomething = () => { console.log('Действието на дъщерния компонент е задействано!'); }; render() { return
Това е дъщерен компонент.
; } }

В този пример ParentComponent използва Ref за достъп до ChildComponent и извикване на неговия метод doSomething.

2. Управление на фокус и селекция

Refs са безценни за управление на фокуса и селекцията в полета за въвеждане и други интерактивни елементи. Това е от решаващо значение за създаването на достъпни и лесни за използване интерфейси.


import React, { useRef, useEffect } from 'react';

function FocusOnMount() {
  const inputRef = useRef(null);

  useEffect(() => {
    if (inputRef.current) {
      inputRef.current.focus();
      inputRef.current.select(); // Селектиране на текста в полето за въвеждане
    }
  }, []);

  return ;
}

Този пример фокусира полето за въвеждане и селектира текста в него веднага след монтирането на компонента.

3. Анимиране на елементи

Refs могат да се използват в комбинация с библиотеки за анимация (като GreenSock или Framer Motion) за директно манипулиране на DOM и създаване на сложни анимации. Това позволява фин контрол върху анимационните последователности.

Пример, използващ чист JavaScript за простота:


import React, { useRef, useEffect } from 'react';

function AnimatedBox() {
  const boxRef = useRef(null);

  useEffect(() => {
    const box = boxRef.current;
    if (box) {
      // Проста анимация: преместване на кутията надясно
      box.animate(
        [
          { transform: 'translateX(0)' },
          { transform: 'translateX(100px)' },
        ],
        {
          duration: 1000, // 1 секунда
          iterations: Infinity, // Повтаряне завинаги
          direction: 'alternate',
        }
      );
    }
  }, []);

  return 
; }

Този пример използва Web Animations API за анимиране на проста кутия, като я движи напред и назад хоризонтално.

Добри практики за използване на React Refs в глобални приложения

При разработването на React приложения за глобална аудитория е важно да се вземе предвид как Refs взаимодействат с интернационализацията (i18n) и локализацията (l10n). Ето някои добри практики:

1. Достъпност (A11y)

Уверете се, че използването на Refs не влияе отрицателно на достъпността. Например, когато програматично фокусирате елементи, вземете предвид реда на фокуса на потребителя и дали промяната на фокуса е подходяща за екранни четци и потребители, използващи клавиатура.


import React, { useRef, useEffect } from 'react';

function AccessibleFocus() {
  const buttonRef = useRef(null);

  useEffect(() => {
    const button = buttonRef.current;
    if (button) {
      // Фокусирай само ако бутонът вече не е фокусиран от потребителя
      if (document.activeElement !== button) {
        button.focus();
      }
    }
  }, []);

  return ;
}

2. Интернационализирани полета за въвеждане

Когато работите с полета за въвеждане, имайте предвид различните методи за въвеждане и набори от символи, използвани в различните езици. Уверете се, че вашите манипулации, базирани на Ref (напр. селекция, позиция на курсора), работят правилно при различни типове въвеждане и локали. Тествайте компонентите си щателно с различни езици и методи за въвеждане.

3. Layout-и отдясно наляво (RTL)

Ако вашето приложение поддържа езици с писане отдясно наляво (RTL), като арабски или иврит, уверете се, че вашите DOM манипулации, използващи Refs, отчитат обърнатия layout. Например, когато анимирате елементи, обмислете обръщане на посоката на анимацията за RTL езици.

4. Съображения за производителност

Въпреки че Refs предоставят мощен начин за взаимодействие с DOM, прекомерната им употреба може да доведе до проблеми с производителността. Директната DOM манипулация заобикаля виртуалния DOM на React и процеса на съгласуване, което потенциално може да доведе до несъответствия и по-бавни актуализации. Използвайте Refs разумно и само когато е необходимо.

Заключение

React Refs, по-конкретно useRef и createRef, са основни инструменти за разработчиците на React. Разбирането на нюансите на всеки подход и кога да се прилагат ефективно е от решаващо значение за изграждането на здрави и производителни приложения. createRef остава стандартът за управление на Refs в класовите компоненти, като гарантира, че всяка инстанция има своя уникална референция. useRef, със своята постоянна природа между рендърите, е идеален за функционални компоненти, предлагайки начин за управление на DOM елементи и запазване на стойности, без да предизвиква ненужни повторни рендирания. Като използвате тези инструменти разумно, можете да подобрите функционалността и потребителското изживяване на вашите React приложения, като се грижите за глобална аудитория с достъпни и производителни интерфейси.

Докато React продължава да се развива, овладяването на тези основни концепции ще ви даде възможност да създавате иновативни и лесни за ползване уеб изживявания, които надхвърлят географските и културни граници. Не забравяйте да дадете приоритет на достъпността, интернационализацията и производителността, за да предоставите наистина глобални приложения.