#javascript #reactjs
#javascript #reactjs
Вопрос:
Я просмотрел документы 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.log("Called in constructor", this.imageRef);
}
componentDidMount() {
console.log("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;
Итак, в конструкторе я создал Ref 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()
с уверенностью или без каких-либо сомнений.
Комментарии:
1. представление объекта в консоли является активным, поэтому, когда вы его разворачиваете, он считывает объект из памяти, который теперь имеет
img
элемент в качестве значения этого ключа. Если вы хотите получить уверенность в состоянии объекта при его регистрации, вам следует глубоко клонировать объект или преобразовать его в строку (с помощью JSON.stringify ) перед его регистрацией2. @FredStark Спасибо, я где-то это читал. Кроме того, это функция браузера или React придает этому какое-то значение?
3. Просто функция браузера! Два текущих ответа, похоже, охватывают все, что я пытался донести, с гораздо большей детализацией
Ответ №1:
Для того, как 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.log(ref);
render('div', 'Hello World', ref);
console.log(ref);
<div id="root"></div>
Итак, в основном — когда вы используете <img ref={this.imageRef} src={urls.regular} alt={description} />
, ref
передается как свойство, и в функции, которая его отображает, он присваивает фактический узел DOM ref.current
.
Ответ №2:
Итак, чтобы ответить на ваш первый вопрос, React присвоит элементу DOM current
свойство ссылки. В вашем случае это означает, что this.imageRef.current
это будет ссылка на элемент изображения, как только компонент отрисовал.
Часть вывода на консоль немного сбивает с толку, но это происходит не из-за какой-то магии, совершаемой React, а скорее из-за того, как консоль браузера обрабатывает объекты, свойства которых меняются после регистрации объекта. Например, если вы запустите следующий код в своей консоли, а затем развернете вывод, вы увидите то же поведение, которое вы видите с ссылкой.
const obj = { current: null }
console.log(obj)
obj.current = 'something'
Вот скриншот того, как это выглядит.