Spec-Zone.ru › React 18

findDOMNode

Устаревшее

Этот API будет удален в будущей основной версии React. См. альтернативы.

findDOMNode находит узел DOM браузера для экземпляра React компонента класса.

const domNode = findDOMNode(componentInstance)
  • Справочник
    • findDOMNode(componentInstance)
  • Использование
    • Поиск корневого узла DOM компонента класса
  • Альтернативы
    • Чтение узла DOM компонента из ссылки
    • Чтение узла DOM дочернего компонента из переданной ссылки
    • Добавление обертывающего <div> элемента

Справочник

findDOMNode(componentInstance)

Вызовите findDOMNode для поиска узла DOM браузера для данного экземпляра React компонента класса.

import { findDOMNode } from 'react-dom';

const domNode = findDOMNode(componentInstance);

См. дополнительные примеры ниже.

Параметры

  • componentInstance: Экземпляр подкласса Component. Например, this внутри компонента класса.

Возвращаемое значение

findDOMNode возвращает ближайший узел DOM браузера в пределах заданного componentInstance. Когда компонент отрисовывается в null, или отрисовывает false, findDOMNode возвращает null. Когда компонент отрисовывает строку, findDOMNode возвращает узел DOM текста, содержащий это значение.

Примечания

  • Компонент может возвращать массив или Fragment с несколькими дочерними элементами. В этом случае findDOMNode, вернёт узел DOM, соответствующий первому непустому дочернему элементу.

  • findDOMNode работает только с подключенными компонентами (то есть компонентами, которые были размещены в DOM). Если вы попытаетесь вызвать это на компоненте, который ещё не подключен (например, вызвав findDOMNode() в render() на компоненте, который ещё не создан), будет выброшено исключение.

  • findDOMNode возвращает результат только на момент вызова. Если дочерний компонент позже отрисует другой узел, вы не сможете быть проинформированы об этом изменении.

  • findDOMNode принимает экземпляр компонента класса, поэтому его нельзя использовать с функциями-компонентами.


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

Поиск корневого узла DOM компонента класса

Вызовите findDOMNode с экземпляром компонента класса (обычно, this) для поиска узла DOM, который он отрисовал.

class AutoselectingInput extends Component {
  componentDidMount() {
    const input = findDOMNode(this);
    input.select()
  }

  render() {
    return <input defaultValue="Hello" />
  }
}

Здесь переменная input будет установлена в элемент DOM <input>. Это позволяет сделать с ним что-то. Например, при нажатии «Показать пример» ниже, при подключении поля ввода, input.select() выбирает весь текст в поле ввода:

import { Component } from 'react';
import { findDOMNode } from 'react-dom';

class AutoselectingInput extends Component {
  componentDidMount() {
    const input = findDOMNode(this);
    input.select()
  }

  render() {
    return <input defaultValue="Hello" />
  }
}

export default AutoselectingInput;


Альтернативы

Чтение узла DOM компонента из ссылки

Код, использующий findDOMNode хрупкий, потому что связь между узлом JSX и кодом, манипулирующим соответствующим узлом DOM, не явна. Например, попробуйте обернуть этот <input /> в <div>:

import { Component } from 'react';
import { findDOMNode } from 'react-dom';

class AutoselectingInput extends Component {
  componentDidMount() {
    const input = findDOMNode(this);
    input.select()
  }
  render() {
    return <input defaultValue="Hello" />
  }
}

export default AutoselectingInput;

Это сломает код, потому что теперь findDOMNode(this) находит узел DOM <div>, но код ожидает узел DOM <input>. Чтобы избежать таких проблем, используйте createRef для управления определённым узлом DOM.

В этом примере findDOMNode больше не используется. Вместо этого inputRef = createRef(null) определён как поле экземпляра класса. Для чтения узла DOM из него можно использовать this.inputRef.current. Для прикрепления к JSX, нужно отрисовать <input ref={this.inputRef} />. Это связывает код, использующий узел DOM, с его JSX:

import { createRef, Component } from 'react';

class AutoselectingInput extends Component {
  inputRef = createRef(null);

  componentDidMount() {
    const input = this.inputRef.current;
    input.select()
  }

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

export default AutoselectingInput;

В современном React без компонентов класса эквивалентный код вызовет useRef вместо этого:

import { useRef, useEffect } from 'react';

export default function AutoselectingInput() {
  const inputRef = useRef(null);

  useEffect(() => {
    const input = inputRef.current;
    input.select();
  }, []);

  return <input ref={inputRef} defaultValue="Hello" />
}

Подробнее о манипулировании DOM с помощью ссылок.


Чтение узла DOM дочернего компонента из переданной ссылки

В этом примере findDOMNode(this) находит узел DOM, принадлежащий другому компоненту. AutoselectingInput отрисовывает MyInput, который является собственным компонентом, отрисовывающим браузерный <input>.

import { Component } from 'react';
import { findDOMNode } from 'react-dom';
import MyInput from './MyInput.js';

class AutoselectingInput extends Component {
  componentDidMount() {
    const input = findDOMNode(this);
    input.select()
  }
  render() {
    return <MyInput />;
  }
}

export default AutoselectingInput;

Обратите внимание, что вызов findDOMNode(this) внутри AutoselectingInput всё ещё даёт вам узел DOM <input>, даже если JSX для этого <input> скрыт внутри компонента MyInput. Это кажется удобным для вышеприведённого примера, но приводит к хрупкому коду. Представьте, что вы хотите позже отредактировать MyInput и добавить обертывающий <div> вокруг него. Это сломает код AutoselectingInput (который ожидает найти <input>).

Чтобы заменить findDOMNode в этом примере, двум компонентам необходимо согласоваться:

  1. AutoSelectingInput должен объявить ссылку, как в предыдущем примере, и передать её <MyInput>.
  2. MyInput должен быть объявлен с помощью forwardRef, чтобы принять эту ссылку и передать её вниз к узлу <input>.

Эта версия делает это, поэтому ей больше не нужен findDOMNode:

import { createRef, Component } from 'react';
import MyInput from './MyInput.js';

class AutoselectingInput extends Component {
  inputRef = createRef(null);

  componentDidMount() {
    const input = this.inputRef.current;
    input.select()
  }

  render() {
    return (
      <MyInput ref={this.inputRef} />
    );
  }
}

export default AutoselectingInput;

Вот как этот код выглядел бы с функциями-компонентами вместо классов:

import { useRef, useEffect } from 'react';
import MyInput from './MyInput.js';

export default function AutoselectingInput() {
  const inputRef = useRef(null);

  useEffect(() => {
    const input = inputRef.current;
    input.select();
  }, []);

  return <MyInput ref={inputRef} defaultValue="Hello" />
}


Добавление обертывающего <div> элемента

Иногда компоненту нужно знать положение и размер его дочерних элементов. Это делает заманчивым найти дочерние элементы с помощью findDOMNode(this), а затем использовать методы DOM, такие как getBoundingClientRect для измерений.

В настоящее время нет прямого эквивалента для этого случая, поэтому findDOMNode устарел, но ещё не полностью удалён из React. В то же время, можно попробовать отрисовать обертывающий <div> узел вокруг содержимого в качестве обходного пути и получить ссылку на этот узел. Однако дополнительные обертки могут нарушить стили.

<div ref={someRef}>
  {children}
</div>

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

© 2013–present Facebook Inc.
Licensed under the Creative Commons Attribution 4.0 International Public License.
https://18.react.dev/reference/react-dom/findDOMNode

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API