2
votes

So I'm reading the literature described here:

https://facebook.github.io/react/docs/more-about-refs.html

And I understand refs in general in how you can use it to access the DOM. But when it talked about callbacks, I got really confused.

To summarize it says (I'm paraphrasing here) that the "callback function gets called when the component is mounted.. it uses the referenced component to be passed into the parameter of the callback in render". I'm sorely confused by this.

So in their example:

render: function() {
    return (
        <TextInput
            ref={function(input) {
                if (input != null) {
                    input.focus();
                }
           }} />
    );
},

So what is the value of "input" when it gets called. Is it the react component of:

<TextInput />

Which I'm also assuming is really a wrapper for:

<input type="text" />

otherwise focus() wouldn't work right?

And my next question is, does ComponentDidMount lifecycle execute before the callback mentioned in the ref in the render lifecycle or after?

because then I see this example (which looks completely different than the non-es6 standard.. it threw me off)

render: function() {
    return <TextInput ref={(c) => this._input = c} />;
},
componentDidMount: function() {
    this._input.focus();
},

which is saying that if you're not using ES6, the logic (namely input.focus()) will be found in the callback found in the render lifecycle. But if you're using ES6, you're moving that logic to componentDidMount lifecycle.

So I'm thinking with the ES6 standard, the callback gets called first, to set the referenced component (I'm assuming is TextInput), as a new alias called "_input", which is recognized and used later in componentDidMount, even though it wasn't declared anywhere else.

Am I right in any of this?

And one more question, if I'm using nonES6 standards, how would I accomplish the same task of having componentDidMount do the logic described in ES6 example? like if I was to do this..

render: function() {
    return (
        <TextInput
            ref={function(c) {
                this._input = c;
           }} />
    );
},
componentDidMount: function() {
    this._input.focus();
},

or am I wrong here?

1

1 Answers

1
votes

For your example to work, you will need to bind this to the ref-callback as React.createClass automatically binds this to the props, but not the callback functions.

render: function() {
    return (
        <TextInput
            ref={function(c) {
                this._input = c;
           }.bind(this)} />
    );
},
componentDidMount: function() {
    this._input.focus();
},

Otherwise this inside the ref is undefined

<TextInput
   ref={function(c) {
     console.log(this); // undefined
     this._input = c;
 }} />

In the ES6 example the arrow function handles the lexical binding of this for you.

JSFiddle