Рефы и DOM – React
Рефы дают возможность получить доступ к DOM-узлам или React-элементам, созданным в рендер-методе.
В обычном потоке данных React родительские компоненты могут взаимодействовать с дочерними только через пропсы. Чтобы модифицировать потомка, вы должны заново отрендерить его с новыми пропсами. Тем не менее, могут возникать ситуации, когда вам требуется императивно изменить дочерний элемент, обойдя обычный поток данных. Подлежащий изменениям дочерний элемент может быть как React-компонентом, так и DOM-элементом. React предоставляет лазейку для обоих случаев.
Когда использовать рефы
Ситуации, в которых использование рефов является оправданным:
- Управление фокусом, выделение текста или воспроизведение медиа.
- Императивный вызов анимаций.
- Интеграция со сторонними DOM-библиотеками.
Избегайте использования рефов в ситуациях, когда задачу можно решить декларативным способом.
Например, вместо того чтобы определять методы open()
close()
в компоненте Dialog
, лучше передавать ему проп isOpen
.
Не злоупотребляйте рефами
Возможно, с первого взгляда вам показалось, что рефы применяются, когда нужно решить какую-то задачу в вашем приложении «во что бы то ни стало». Если у вас сложилось такое впечатление, сделайте паузу и обдумайте, где должно храниться конкретное состояние в иерархии компонентов. Часто становится очевидно, что правильным местом для хранения состояния является верхний уровень в иерархии. Подробнее об этом — в главе Подъём состояния.
Примечание
Приведённые ниже примеры были обновлены с использованием API-метода
добавленного в React 16.3. Если вы используете более старую версию React, мы рекомендуем использовать колбэк-рефы.
React.createRef()
Создание рефов
Рефы создаются с помощью React.createRef()
и прикрепляются к React-элементам через ref
атрибут. Обычно рефы присваиваются свойству экземпляра класса в конструкторе, чтобы на них можно было ссылаться из любой части компонента.
class MyComponent extends React.Component { constructor(props) { super(props); this.myRef = React.createRef(); } render() { return <div ref={this.myRef} />; } }
Доступ к рефам
Когда реф передаётся элементу в методе render
, ссылка на данный узел доступна через свойство рефа current
.
const node = this.myRef.current;
Значение рефа отличается в зависимости от типа узла:
- Когда атрибут
ref
используется с HTML-элементом, свойствоcurrent
созданного рефа в конструкторе с помощьюReact.createRef()
получает соответствующий DOM-элемент. - Когда атрибут
ref
используется с классовым компонентом, свойствоcurrent
объекта-рефа получает экземпляр смонтированного компонента. ref
атрибут с функциональными компонентами, потому что для них не создаётся экземпляров.
Представленные ниже примеры демонстрируют отличия в зависимости от типа узла.
Добавление рефа к DOM-элементу
В представленном ниже примере ref
используется для хранения ссылки на DOM-элемент.
class CustomTextInput extends React.Component { constructor(props) { super(props); this.textInput = React.createRef(); this.focusTextInput = this.focusTextInput.bind(this); } focusTextInput() { this.textInput.current.focus(); } render() { return ( <div> <input type="text" ref={this.textInput} /> <input type="button" value="Фокус на текстовом поле" onClick={this.focusTextInput} /> </div> ); } }
React присвоит DOM-элемент свойству current
при монтировании компонента и присвоит обратно значение null
при размонтировании. Обновление свойства ref
происходит перед вызовом методов componentDidMount
и componentDidUpdate
.
Добавление рефа к классовому компоненту
Для того чтобы произвести имитацию клика по
из прошлого примера сразу же после монтирования, можно использовать реф, чтобы получить доступ к пользовательскому <input>
и явно вызвать его метод focusTextInput
:
class AutoFocusTextInput extends React.Component {
constructor(props) {
super(props);
this.textInput = React.createRef(); }
componentDidMount() {
this.textInput.current.focusTextInput(); }
render() {
return (
<CustomTextInput ref={this.textInput} /> );
}
}
Обратите внимание, что это сработает только в том случае, если CustomTextInput
объявлен как классовый компонент:
class CustomTextInput extends React.Component { }
Рефы и функциональные компоненты
По умолчанию нельзя использовать атрибут ref
с функциональными компонентами, потому что для них не создаётся экземпляров:
function MyFunctionComponent() { return <input />;
}
class Parent extends React.
Component {
constructor(props) {
super(props);
this.textInput = React.createRef(); }
render() {
return (
<MyFunctionComponent ref={this.textInput} /> );
}
}
Если вам нужен реф на функциональный компонент, можете воспользоваться forwardRef
(возможно вместе с
), либо превратить его в классовый компонент.
Тем не менее, можно использовать атрибут ref
внутри функционального компонента при условии, что он ссылается на DOM-элемент или классовый компонент:
function CustomTextInput(props) {
const textInput = useRef(null);
function handleClick() {
textInput.current.focus(); }
return (
<div>
<input
type="text"
ref={textInput} /> <input
type="button"
value="Фокус на поле для ввода текста"
onClick={handleClick}
/>
</div>
);
}
Передача DOM-рефов родительским компонентам

Несмотря на то, что можно было бы добавить реф к дочернему компоненту, такое решение не является идеальным, т. к. вы получите экземпляр компонента вместо DOM-узла. Кроме того, это не сработает с функциональными компонентами.
Если вы работаете с React 16.3 или новее, мы рекомендуем использовать перенаправление рефов для таких случаев.
Если вы используете React версии 16.2 или ниже, или если вам нужно решение более гибкое, чем перенаправление рефов, вы можете использовать данный альтернативный подход и явно передавать реф как проп с другим именем.
По возможности, мы советуем избегать передачи DOM-узлов, но это может быть полезной лазейкой. Заметим, что данный подход требует добавления кода в дочерний компонент. Если у вас нет никакого контроля над реализацией дочернего компонента, последним вариантом является использование findDOMNode()
, но такое решение не рекомендуется и не поддерживается в StrictMode
.
Колбэк-рефы
Кроме того, React поддерживает другой способ определения рефов, который называется «колбэк-рефы» и предоставляет более полный контроль над их присвоением и сбросом.
Вместо того, чтобы передавать атрибут ref
созданный с помощью createRef()
, вы можете передать функцию. Данная функция получит экземпляр React-компонента или HTML DOM-элемент в качестве аргумента, которые потом могут быть сохранены или доступны в любом другом месте.
Представленный ниже пример реализует общий паттерн: использование колбэка в ref
для хранения ссылки на DOM-узел в свойстве экземпляра.
class CustomTextInput extends React.Component { constructor(props) { super(props); this.textInput = null; this.setTextInputRef = element => { this.textInput = element; }; this.focusTextInput = () => { if (this.textInput) this.textInput.focus(); }; } componentDidMount() { this.focusTextInput(); } render() { return ( <div> <input type="text" ref={this.setTextInputRef} /> <input type="button" value="Focus the text input" onClick={this.focusTextInput} /> </div> ); } }
React вызовет ref
колбэк с DOM-элементом при монтировании компонента, а также вызовет его со значением null
при размонтировании. Рефы будут хранить актуальное значение перед вызовом методов componentDidMount
или componentDidUpdate
.
Вы можете передавать колбэк-рефы между компонентами точно так же, как и объектные рефы, созданные через React.
. createRef()
function CustomTextInput(props) {
return (
<div>
<input ref={props.inputRef} /> </div>
);
}
class Parent extends React.Component {
render() {
return (
<CustomTextInput
inputRef={el => this.inputElement = el} />
);
}
}
В представленном выше примере, Parent
передаёт свой колбэк-реф как проп inputRef
компоненту CustomTextInput
, а CustomTextInput
передаёт ту же самую функцию как специальный атрибут ref
элементу <input>
. В итоге свойство this.inputElement
компонента Parent
будет хранить значение DOM-узла, соответствующего элементу <input>
в CustomTextInput
.
Устаревший API: строковые рефы
Если вы уже работали с React ранее, возможно вы знакомы с более старым API, в котором атрибут ref
является строкой, например"textInput"
, а DOM-узел доступен в this.
. Мы не советуем пользоваться таким решением, т. к. у строковых рефов есть некоторые недостатки, они являются устаревшими и будут удалены в одном из будущих релизов. refs.textInput
Примечание
Если вы используете
this.refs.textInput
для доступа к рефам в своих проектах, мы рекомендуем перейти к использованию паттерна с колбэком илиcreateRef
API.
Предостережения насчёт колбэк-рефов
Если ref
колбэк определён как встроенная функция, колбэк будет вызван дважды во время обновлений: первый раз со значением null
, а затем снова с DOM-элементом. Это связано с тем, что с каждым рендером создаётся новый экземпляр функции, поэтому React должен очистить старый реф и задать новый. Такого поведения можно избежать, если колбэк в ref
будет определён с привязанным к классу контекстом, но, заметим, что это не будет играть роли в большинстве случаев.
HTML Ref Tag — это такая штука?
Я уверен, что сейчас почувствую себя абсолютно глупо, но разве там не должен быть тег ‘ref’? Я нигде не могу найти информацию об этом. То, что я ищу, — это тег, который можно использовать при цитировании/ссылках на материалы из внешних источников, таких как Википедия.
Спасибо!
htmlПоделиться Источник jpppp 29 октября 2013 в 03:26
2 ответа
-
angular.element.cache, что это за штука?
недавно я борюсь с ошибкой, которая angular не работает на странице. Я проверил это и обнаружил, что каким-то образом все свойства удалены из angular.element.cache Может ли кто-нибудь объяснить, что это за штука и по какой причине ее нужно очистить ?
-
Tag Helpers-Self closing HTML tags — это плохая привычка?
Я включаю TagHelpers в свой проект MVC vNext, и я понял, что они не работают, когда я сам закрываю теги HTML. @addTagHelper *, Microsoft.AspNet.Mvc.TagHelpers <label asp-for=FirstName/> <!— self closing tag —> <span asp-validation-for=FirstName/> <!— self closing tag —>.
..
2
Да, она существует. Однако он называется <cite>
.
Пример использования из MDN :
More information can be found in <cite>[ISO-0000]</cite>
Поделиться Brad 29 октября 2013 в 03:30
Поделиться A Fog 27 августа 2018 в 09:37
Похожие вопросы:
Что это за змееподобная длинная штука на ушах?
Я нашел это на веб-странице. Что это за длинная штука растет из этих ушей? Он встречается даже в исходном коде. Как это закодировано?…
git tag: fatal: не удалось разрешить ‘HEAD’ как действительный ref
Я клонирую одну ветвь из репозитория и создаю тег в скрипте python. Команды следующие. git clone -b master —single-branch <repository adress> git tag -a testag -m ‘test’ Он успешно. ..
Stray start tag html и head
Я новый программист, работающий на своем первом сайте RoR (с реализованной темой bootstrap) и имеющий некоторые (казалось бы, простые) проблемы с HTML, замеченные с проблемами обмена изображениями…
angular.element.cache, что это за штука?
недавно я борюсь с ошибкой, которая angular не работает на странице. Я проверил это и обнаружил, что каким-то образом все свойства удалены из angular.element.cache Может ли кто-нибудь объяснить, что…
Tag Helpers-Self closing HTML tags — это плохая привычка?
Я включаю TagHelpers в свой проект MVC vNext, и я понял, что они не работают, когда я сам закрываю теги HTML. @addTagHelper *, Microsoft.AspNet.Mvc.TagHelpers <label asp-for=FirstName/>…
git tag: fatal: не удалось разрешить ‘refs/remotes/my_tag_name’ как действительный ref
В настоящее время я клонирую РЕПО svn, которое имеет стандартную компоновку. В настоящее время он содержит код, соответствующий одному приложению iOS и одному приложению Android. Теги указывают,…
Событие Kotlinx-html ref
Я заметил следующую функцию в базе кода, которая использует kotlinx html , и ее довольно трудно полностью понять: private fun <E : HTMLElement> Tag.xrefImpl(prop: KMutableProperty0<E?>)…
Как отключить функцию зеркала VS Code auto-rename-tag / HTML?
Я хотел иметь возможность легко редактировать теги HTML вместе. Мне показалось, что это такая простая вещь для реализации в наши дни , поэтому я установил это расширение auto-rename-tag, и оно…
Как это исключено !Ref tag от check-yaml git hook?
Существует файл serverless.yaml , который содержит такую строку: VpcId: !Ref MyVpc Файлы Yaml проверяются крючком check-yaml git , который вызывается командой pre-commit . Таким образом, запуск…
Git pull невозможно обновить локальный ref
У меня есть что-то странное с тех пор, как мы начали использовать субмодули для git. Я нахожусь на Windows 10 и использую либо Tortoise git, либо Powershell, либо cmd, либо интерпретатор команд…
htmlreference.ru — Простой справочник по html
htmlreference.ru — Простой справочник по htmlПростой справочник по html
a | базовые | строчные | парные |
abbr | базовые | строчные | парные |
address | базовые | блочные | парные |
area | базовые | строчные | одинарные |
aside | семантические | блочные | парные |
audio | базовые | блочные | парные |
b | базовые | строчные | парные |
base | базовые | — | одинарные |
bdo | базовые | строчные | парные |
blockquote | базовые | блочные | парные |
body | базовые | блочные | парные |
br | базовые | строчные | одинарные |
button | формы | строчные | парные |
caption | табличные | блочные | парные |
cite | семантические | строчные | парные |
col | табличные | строчные | одинарные |
colgroup | табличные | строчные | парные |
datalist | базовые | блочные | парные |
dd | списки | строчные | парные |
del | семантические | строчные | парные |
details | базовые | блочные | парные |
dialog | экспериментальные | блочные | парные |
div | базовые | блочные | парные |
dl | списки | блочные | парные |
dt | списки | блочные | парные |
em | базовые | строчные | парные |
fieldset | формы | блочные | парные |
figcaption | семантические | блочные | парные |
figure | семантические | блочные | парные |
footer | семантические | блочные | парные |
h2 | семантические | блочные | парные |
h3 | семантические | блочные | парные |
h4 | семантические | блочные | парные |
h5 | семантические | блочные | парные |
h5 | семантические | блочные | парные |
head | базовые | блочные | парные |
header | семантические | блочные | парные |
hgroup | семантические | блочные | парные |
hr | базовые | блочные | одинарные |
i | базовые | строчные | парные |
iframe | базовые | блочные | парные |
img | базовые | строчные | одинарные |
input | формы | строчные | одинарные |
Последние изменения: 19. 10.2020, 21:17
Атрибут | Принадлежит к | Описание |
---|---|---|
принять | <вход> | Задает типы файлов, которые принимает сервер (только для type = «file»). |
кодировка приема | <форма> | Задает кодировки символов, которые должны использоваться для формы. представление |
ключ доступа | Глобальные атрибуты | Задает сочетание клавиш для активации / фокусировки элемента |
действие | <форма> | Указывает, куда отправлять данные формы при отправке формы |
выровнять | Не поддерживается в HTML 5. | Задает выравнивание по окружающим элементам. Используйте CSS вместо |
alt | , |
Задает альтернативный текст, если исходный элемент не отображается. |
асинхронный | <сценарий> | Указывает, что сценарий выполняется асинхронно (только для внешних скрипты) |
автозаполнение | <форма>, <ввод> | Указывает, должен ли элемент |
автофокус | <кнопка>, , | Указывает, что элемент должен автоматически получать фокус, когда страница грузы |
автовоспроизведение | <аудио>, <видео> | Указывает, что аудио / видео будет воспроизводиться, как только оно будет готово. |
bgcolor | Не поддерживается в HTML 5. | Задает цвет фона элемента. Используйте CSS вместо |
граница | Не поддерживается в HTML 5. | Задает ширину границы элемента. Используйте CSS вместо |
кодировка | ,
|