Я сопоставил массив объектов из внешнего API, который успешно отображает их содержимое. Теперь я пытаюсь получить доступ к их отдельным clientHeights через React ref, но, похоже, он выводит ТОЛЬКО первый элемент, когда я вхожу в свою консоль:
class ImageList extends React.Component{
constructor(props){
super(props)
this.imageRef = React.createRef()
}
componentDidMount(){
console.info(this.imageRef)
}
render(){
const images= this.props.images.map((image)=>{
return(
<img ref = {this.imageRef}
key = {image.id}
src = {image.urls.regular}
alt = {image.description} />
)})
return(
<div className = "image-list" >
{images}
</div>
)
}
}
Я пытаюсь получить все их clientHeights, а не только первый. Спасибо
Даже если мои элементы отображаются? ref = {this.imageRef} key = {image.id} src = {image.urls.regular} alt = {image.description}
. key, src и alt сопоставляются и создают разные значения для каждого отображаемого элемента, так почему Ref отличается
key, src и alt — все значения, которые вы передаете компоненту. Хотя вы также передаете что-то компоненту с помощью ref
, компонент в конечном итоге назначает ему ссылку на свой базовый элемент DOM. Это означает, что у вас есть компоненты изображения X, которые пытаются присвоить свой элемент DOM одной и той же ссылке. Это не может работать.
Ваш код назначит каждому узлу img значение this.imageRef
. Я не уверен, почему он сохраняет первую ссылку, но в любом случае он не будет работать так, как вы ожидаете. Чтобы получить массив узлов img, вам нужно, чтобы ссылка была массивом и добавляла в него каждый узел. ref
prop может быть функцией, поэтому попробуйте что-то вроде этого
class ImageList extends React.Component{
constructor(props){
super(props)
}
componentDidMount(){
console.info(this.imageRefs)
}
render(){
this.imageRefs = []
const images= this.props.images.map((image)=>{
return(
<img ref = {ref => {this.imageRefs.push(ref)}}
key = {image.id}
src = {image.urls.regular}
alt = {image.description} />
)})
return(
<div className = "image-list" >
{images}
</div>
)
}
}
Вау, это сработало. Пожалуйста, если это не слишком беспокоит, можете ли вы объяснить, как ваш код работал без инициализации React.createRef()? Также не могли бы вы объяснить эту строку кода ref = {ref => {this.imageRefs.push(ref)}
. Я не понимаю, почему вставляемая ссылка имеет значения, она была ПРОСТО определена только внутри функции. Или это нормальный синтаксис? Я впервые использую Refs, и я извиняюсь за кучу вопросов, спасибо. Кроме того, мой исходный код полностью работал в этом уроке, который я смотрю, поэтому я понятия не имею, что не так.
@Chijindu: см. reactjs.org/docs/refs-and-the-dom.html#callback-refs
React.createRef()
нужен, если вы хотите, чтобы волшебное ref = {this.imageRef}
сработало. Во времена до React.createRef()
мы также использовали простые свойства для хранения ссылок, но тогда они были бы null
при первом рендеринге, потому что узлы DOM впервые создаются только в конце первого рендеринга. Это вызвало много проблем у разработчиков, поэтому команда React придумала React.createRef()
. По сути, он создает объект-оболочку, который всегда существует и имеет свойство current
, которое может быть null
или ссылкой на узел DOM, но, по крайней мере, само свойство компонента никогда не бывает null
.
Поддерживая массив ссылок на узлы DOM, вы сами делаете то, что сделал бы React.createRef()
, но используете массив вместо объекта-оболочки, чтобы вы могли хранить ссылки на несколько узлов DOM.
Другой способ, который я получил (полученный из учебника), - это отобразить изображение и его содержимое как ДРУГОЙ компонент (назовите его ImageCard, где я сейчас поместил ссылку), а затем отобразить этот компонент вместо исходного тега <img/>
следующим образом:
class ImageList extends React.Component{
render(){
const images= this.props.images.map((image)=>{
return(
<ImageCard key = {image.id} image= {image}/>
)})
console.info(images);
return(
<div className = "image-list" >
{images}
</div>
)
}
}
Это позволяет отображать любые манипуляции с компонентом ImageCard. Я понял это только сейчас, после повторного просмотра, кстати
Свойство или переменная может содержать только одно значение, поэтому
this.imageRef
может содержать ссылку только на один из элементов. Вам нужно создать ссылку для каждого изображения.