Я просмотрел документацию React для React Refs, и вот что там написано createRef()
createRef() получает базовый элемент DOM в качестве своего текущего свойства. Когда атрибут ref используется в компоненте пользовательского класса, объект ref получает смонтированный экземпляр компонента в качестве своего текущего .
У меня есть несколько вопросов по этому поводу. Сначала посмотрите на компонент ниже.
import React, { Component } from "react";
class ImageCard extends Component {
constructor(props) {
super(props);
this.imageRef = React.createRef();
console.info("Called in constructor", this.imageRef);
}
componentDidMount() {
console.info("Called when component did mount ", this.imageRef);
}
render() {
const { description, urls } = this.props.image;
return (
<div>
<img ref = {this.imageRef} src = {urls.regular} alt = {description} />
</div>
);
}
}
export default ImageCard;
Итак, в конструкторе я создал React Ref и присвоил ему свойство с именем imageRef
. И в методе render()
я передал этот React Ref элементу img
React в качестве атрибута как ref
.
Что здесь делает React Ref?
img
в конечном итоге станет объектом, который имеет свойство, называемое ref со значением this.imageRef
, как он получает img
в качестве своего текущего свойства?
Если бы это было что-то вроде этого this.imageRef.current = img(object)
, возможно. Но я не понимаю вышеуказанный способ, т.е. ref = {this.imageRef}
Кроме того, для обоих операторов консоли это результат, который я получаю.
Итак, в конструкторе текущим свойством является null
, которое действительно. Но, когда я расширяю его, он имеет все свойства img
, напечатанные в componentDidMount
, то есть также clinetHeght
Как?
Я не знаю, если есть краткое объяснение этого или кто-то должен исправить целую страницу. Если это слишком много, чтобы ответить, будут полезны внешние ссылки или ссылки.
Меня также не интересуют подробности реализации библиотеки, просто обзор был бы полезен, чтобы я мог использовать React.createRef()
с уверенностью или без каких-либо сомнений.
@FredStark Спасибо, я где-то это прочитал. Кроме того, это функция браузера или React прикрепляет к этому некоторые наблюдаемые?
Просто функция браузера! Два текущих ответа, похоже, охватывают все, что я пытался донести, с гораздо более подробной информацией.
Итак, чтобы ответить на ваш первый вопрос, React назначит элемент DOM свойству current
ссылки. В вашем случае это означает, что this.imageRef.current
будет ссылкой на элемент изображения, как только компонент отобразится.
Часть вывода на консоль немного сбивает с толку, но это не из-за какой-то магии, проделанной React, а скорее из-за того, как консоль браузера обрабатывает объекты, свойства которых изменяются после того, как объект был зарегистрирован. Например, если вы запустите следующий код в своей консоли, а затем расширите вывод, вы увидите то же поведение, что и с ref.
const obj = { current: null }
console.info(obj)
obj.current = 'something'
Вот скриншот того, как это выглядит.
Чтобы понять, как назначается ref
, вы должны помнить, что JSX скомпилирован в старый добрый javascript. Очень упрощенный пример того, что происходит под обложкой, выглядит примерно так:
function createRef(initialValue) {
return {
current: initialValue
}
}
const root = document.getElementById('root');
function render(elementType, innerText, ref) {
const el = document.createElement(elementType);
if (ref) {
ref.current = el;
}
el.innerText = innerText;
root.replaceChildren(el);
}
const ref = createRef(null);
console.info(ref);
render('div', 'Hello World', ref);
console.info(ref);
<div id = "root"></div>
В общем, когда вы используете <img ref = {this.imageRef} src = {urls.regular} alt = {description} />
, ref
передается как свойство, и в функции, которая его визуализирует, она присваивает фактическому узлу DOM значение ref.current
.
представление объекта в консоли активно, поэтому, когда вы его разворачиваете, оно считывает объект из памяти, который теперь имеет элемент
img
в качестве значения этого ключа. Если вы хотите быть уверенным в состоянии объекта при его регистрации, вы должны глубоко клонировать объект или преобразовать его в строку (с помощью JSON.stringify) перед его регистрацией.