useRef Hook как изменяемый объект ссылки.

Официальный ответ документация определить useRef как:

Хук useRef — это функция, которая возвращает изменяемый объект ref, чье свойство .current инициализируется переданным аргументом (initialValue). Возвращенный объект будет сохраняться в течение всего срока службы компонента.

const refContainer = useRef(initialValue);

Распространенным вариантом использования является императивный доступ к дочернему элементу:

function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
    // `current` points to the mounted text input element
    inputEl.current.focus();
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}

По сути, useRef похож на «коробку», которая может содержать изменяемое значение в своем свойстве .current. Возможно, вы знакомы с ссылками прежде всего как со способом доступа к DOM. Если вы передадите объект ref в React с помощью

, React установит для своего свойства .current значение соответствующего узла DOM при каждом изменении этого узла.

Однако useRef() полезен не только для атрибута ref. Это удобно для хранения любого изменяемого значения, аналогично тому, как вы используете поля экземпляра в классах. Давайте разберемся с этим на примере.

Если вы знакомы с компонентами класса React, вы могли заметить, что функциональный компонент — это компонент React без функции рендеринга. Все, что определено в теле функции, является функцией рендеринга, которая в конце возвращает JSX.

Это означает, что всякий раз, когда происходит изменение состояния, выполняются все коды в функциональном компоненте. Это означает, что если у нас есть переменная экземпляра внутри функционального компонента, то при каждом рендеринге она будет инициализироваться значением по умолчанию. Давайте докажем это. Скажем, у нас есть переменная экземпляра, которая записывает количество изменений состояния после монтирования компонента. Сначала мы напишем что-то вроде ниже —

import React, {useState} from 'react';
const child = {
  padding: '25px',
  margin: '25px',
  border: '2px solid blue'
};

const Child = (prop) => {
  console.log("fuction called....");
  let counter = 0;
  let [myState, setMyState] = useState("A");
  
  let updateState = () => {
    counter++;
    setMyState(myState + "-u-");
    console.log("counter: "+ counter);
  }

  return (
    <div style={child}>
      <div>
        <div>MyState : {myState}</div>
        <input type="button" onClick = {() => updateState()} value="Update State"></input>
      </div>
    </div>
  );
}

export default Child;

Но здесь мы видим проблему, заключающуюся в том, что каждое значение счетчика stateChage равно 1, и причина проста в том, что каждая переменная счетчика рендеринга переназначается.

1.JPG

Требование здесь: оно должно увеличиваться при каждом изменении состояния. Теперь давайте изменим эту переменную экземпляра, чтобы она создавалась с помощью useRef. И теперь один и тот же перенастроенный объект будет использоваться всегда и будет оставаться закрытым для Компонента на протяжении всего времени жизни Компонента.

import React, {useState, useRef} from 'react';
const child = {
  padding: '25px',
  margin: '25px',
  border: '2px solid blue'
};

const Child = (prop) => {
  console.log("fuction called....");
  let counter = useRef(0);
  let [myState, setMyState] = useState("A");
  
  let updateState = () => {
    // Now we can update the current property of Referenced object as below.
    counter.current++;
    setMyState(myState + "-u-");
    console.log("counter: "+ counter.current);
  }

  return (
    <div style={child}>
      <div>
        <div>MyState : {myState}</div>
        <input type="button" onClick = {() => updateState()} value="Update State"></input>
      </div>
    </div>
  );
}

export default Child;

Теперь, наконец, мы получаем ожидаемый результат.

2.JPG

Наконец, имейте в виду, что useRef не уведомляет вас об изменении его содержимого. Изменение свойства .current не приводит к повторному рендерингу. Если вы хотите запустить некоторый код, когда React прикрепляет или отсоединяет ссылку от узла DOM, вы можете вместо этого использовать ссылку обратного вызова.

КОГДА ИСПОЛЬЗОВАТЬ АТРИБУТ REACT REACT?

Но использование атрибута ref не всегда является хорошей идеей. Общее правило – избегать этого. В официальной документации React упоминаются три случая, когда вы можете использовать его, потому что у вас нет другого выбора.

  • Управление фокусом, выделением текста или воспроизведением мультимедиа.
  • Интеграция со сторонними библиотеками DOM.
  • Запуск императивной анимации.

Во-первых, вы можете использовать атрибут ref для доступа к DOM API (Что такое API?). Вы можете получить значение элемента ввода, а также вызвать такие методы, как focus(). Это дает вам контроль над DOM API, например, для использования медиа-элементов.

Во-вторых, вы можете использовать его для интеграции со сторонними библиотеками, использующими DOM. D3.js является таким вариантом использования, потому что он должен подключаться к DOM и имеет свой собственный API для работы с DOM. Например, вы можете захотеть интегрировать компонент D3 в иерархию компонентов React. Поэтому вы можете использовать атрибут ref в качестве точки входа для компонента D3. Вы покидаете мир React и получаете доступ к миру D3.

И последнее, но не менее важное: вы можете принудительно запускать анимацию для своих элементов.

Это единственные случаи, когда вы должны использовать атрибут ref в вашем React DOM.

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *