How does React.createRef() actually work?

I went through React docs for React Refs, and this what it says about createRef()

createRef() receives the underlying DOM element as its current property. When the ref attribute is used on a custom class component, the ref object receives the mounted instance of the component as its current .

I have some questions on this. First have look at below component.

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;

So, in the constructor I created a React Ref, and assigned to a property called imageRef. And, in the render() method, I passed that React Ref to img React element as an attribute as a ref.

What does React Ref does here?

img will eventually become an object which has a property called ref with value this.imageRef, how it receive img as it’s current property?

If it was something like this this.imageRef.current = img(object), It can be possibly. But I don’t understand the above way i.e ref={this.imageRef}

Also, For both console statements this is the output that I get.

How does React.createRef() actually work?

So, in the constructor current property is null that is valid. But, when I expand it, It has all properties that of img printed in componentDidMount i.e also clinetHeght How?

I don’t know, If there is short explanation for this or someone have to right a full page. If that’s too big to answer, external links or references would be helpful.

I also am not interested in nitty-gritty of library implementation, just an overview would be helpful so that I can use React.createRef() with confidence or without any doubt.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

For how ref gets assigned, you have to remember that JSX compiled down to plain old javascript. A very simplified example of what is going on under the covers is something like this:

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>

So basically – when you use <img ref={this.imageRef} src={urls.regular} alt={description} />, the ref is passed as a property, and in the function that renders it, it assigns the actual DOM node to ref.current.

Method 2

So, to answer your first question, React will assign the DOM element to the current property of the ref. In your case, that means that this.imageRef.current will be a reference to the image element as soon as the component has rendered.

The console output portion makes it a bit confusing, but it is not due to some magic done by React, but rather it is due to how the browser console handles objects whose properties change after the object has been logged. For example, if you run the following code in your console and then expand the output, you will see the same behavior your are seeing with the ref.

const obj = { current: null }
console.log(obj)
obj.current = 'something'

Here is a screenshot of that what that looks like.

How does React.createRef() actually work?


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x