Рефы React

React поддерживает очень особое свойствоRef, которое можно использовать для привязки к любому компоненту, выводимому render().

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

В React refs предоставляют способ доступа к DOM-элементам или экземплярам компонентов. Используя refs, вы можете напрямую управлять DOM-элементами или получать экземпляры дочерних компонентов; это подходит для таких сценариев, как управление фокусом, выделение текста, воспроизведение медиа, запуск принудительных анимаций или интеграция сторонних DOM-библиотек.

Использование

Используйте React.createRef или useRef для создания и доступа к refs.

React.createRef обычно используется в классовых компонентах, тогда как useRef — это Hook, обычно используемый в функциональных компонентах.

Кроме того, привязку this в функциях-обработчиках событий можно выполнить с помощью синтаксиса свойств класса, чтобы избежать создания новой функции при каждом рендере.

  • Создание Ref: Используйте его в конструкторе классового компонентаReact.createRefСоздайте объект ref и присвойте его свойству экземпляра компонента.
  • Привязка Ref: Вrenderметоде привяжите объект ref к DOM-элементу, на который нужно ссылаться.
  • Доступ к Ref: В других методах компонента, черезthis.myInputRef.currentполучить доступ к привязанному DOM-элементу и управлять его свойствами и методами.

Полный пример

Вы можете использовать это, чтобы получить текущий React-компонент, или использовать ref, чтобы получить ссылку на компонент, как показано в следующем примере:

Пример React

class MyComponent extends React.Component { constructor(props) { super(props); this.myInputRef = React.createRef(); } handleClick = () => { //Используйте нативный DOM API для получения фокуса this.myInputRef.current.focus(); } render() { return ( <div> <input type="text" ref={this.myInputRef} /> <input type="button" value="Нажмите, чтобы сфокусировать поле ввода" onClick={this.handleClick} /> </div> ); } }

Попробуйте сами »

В примере мы получили ссылку на экземпляр, лежащий в основе поля ввода, и после нажатия кнопки поле ввода получает фокус.

Мы также можем использовать метод getDOMNode() для получения DOM-элемента.


Создание Refs

React предоставляет метод React.createRef для создания рефов.

Пример

import React from 'react';
import ReactDOM from 'react-dom';

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

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

  render() {
    return <input type="text" ref={this.myRef} />;
  }
}

const root = ReactDOM.createRoot(document.getElementById("root"));
// Отрисовать компонент MyComponent
root.render(<MyComponent />);

Рефы-колбэки

Другой способ создания рефов — использовать функцию обратного вызова. Этот подход был распространён до React 16.3; теперь React.createRef более предпочтителен.

Пример

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

  componentDidMount() {
    if (this.myRef) {
      this.myRef.focus();
    }
  }

  render() {
    return <input type="text" ref={this.setMyRef} />;
  }
}

const root = ReactDOM.createRoot(document.getElementById("root"));
// Отрисовать компонент MyComponent
root.render(<MyComponent />);

Доступ к DOM-элементам с помощью рефов

С помощью рефов можно напрямую обращаться к DOM-элементам и манипулировать ими.

Пример

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

  handleClick = () => {
    this.myRef.current.style.backgroundColor = 'yellow';
  };

  render() {
    return (
      <div>
        <input type="text" ref={this.myRef} />
        <button onClick={this.handleClick}>Изменить фон</button>
      </div>
    );
  }
}

const root = ReactDOM.createRoot(document.getElementById("root"));
// Отрисовать компонент MyComponent
root.render(<MyComponent />);

Доступ к экземплярам дочерних компонентов с помощью рефов

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

Пример

class ChildComponent extends React.Component {
  focusInput = () => {
    this.inputRef.current.focus();
  };

  constructor(props) {
    super(props);
    this.inputRef = React.createRef();
  }

  render() {
    return <input type="text" ref={this.inputRef} />;
  }
}

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

  handleClick = () => {
    this.childRef.current.focusInput();
  };

  render() {
    return (
      <div>
        <ChildComponent ref={this.childRef} />
        <button onClick={this.handleClick}>Фокусировать дочерний ввод</button>
      </div>
    );
  }
}

const root = ReactDOM.createRoot(document.getElementById("root"));
// Отрисовать компонент MyComponent
root.render(<MyComponent />);

Использование хука useRef (Функциональные компоненты)

В функциональных компонентах вы можете использовать хук useRef для создания рефов.

Пример

import React, { useRef } from 'react';
import ReactDOM from 'react-dom';

const MyComponent = () => {
  const inputRef = useRef(null);

  const handleClick = () => {
    inputRef.current.focus();
  };

  return (
    <div>
      <input type="text" ref={inputRef} />
      <button onClick={handleClick}>Фокусировать ввод</button>
    </div>
  );
};

const root = ReactDOM.createRoot(document.getElementById("root"));
// Отрисовать компонент MyComponent
root.render(<MyComponent />);

Итог

  • Создание рефов: использование в классовых компонентахReact.createRef, использование в функциональных компонентахuseRef Хук.
  • Доступ к DOM-элементам: Прямой доступ к DOM-элементам и управление ими через refs.
  • Доступ к экземплярам дочерних компонентов: Доступ к методам или свойствам экземпляра дочернего компонента через refs.
  • Настройка предоставляемых значений экземпляра: ИспользуйтеuseImperativeHandleиforwardRef, чтобы настроить значение экземпляра, которое дочерний компонент предоставляет родительскому компоненту.
  • Refs в конкурентном режиме: Refs по-прежнему работают нормально в конкурентном режиме и могут комбинироваться сuseTransitionи другими хуками, связанными с конкурентным режимом.
Другие расширения