8
votes

So, extract from https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute

The ref attribute can be a callback function instead of a name. This callback will be executed immediately after the component is mounted. The referenced component will be passed in as a parameter, and the callback function may use the component immediately, or save the reference for future use (or both).

It then only gives an example of using the component immediately. I'm trying to find out how i would use this function to access the component immediately, and save the component for future use, as it says we are able to do.

To continue their specific focus() and theInput example, how would i call focus() on the input element, and save it to the theInput key in refs?

Or put another way, how would i make the console.log in this fiddle return an object with a theInput key of the input element's component ref: https://jsfiddle.net/qo3p3fh1/1/

5
I have tried returning a value: <input type="text" ref={ function(component) { React.findDOMNode( component ).focus(); return 'theInput'; } } /> - no luckstef
I have tried assigning it manually to this.refs var self = this; <input type="text" ref={ function(component) { self.refs.theInput = component; React.findDOMNode( component ).focus(); } } /> (more out of desperation than anything else - i know the official advice is not to use this.refs inside render functions). still no luckstef

5 Answers

7
votes

I do not really understand the chosen answer, and the fiddle just returns an empty object.

Further read from this doc at the ES6 usage, you will find:

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

So what you need to do is to assign that component to a var that you can hang on to, possibly to this like in the example, and later you can use this._input to control your component.

4
votes

I included the code here for completeness.

HTML from your fiddle:

<script src="https://facebook.github.io/react/js/jsfiddle-integration.js"></script>

<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

Updated react script changing the way refs are used, fiddle here (https://jsfiddle.net/mark1z/q9yg70ak/)

var Hello = React.createClass({
    componentDidMount: function(){
        React.findDOMNode(this.refs['theInput']).focus();
    },
    render: function() {
        return (
          <div>
            <input type="text" ref='theInput'/>
            <input type="button" onClick={ this.submitForm } value="Submit!" />
          </div>
        );
    },
    submitForm: function() {
      console.log( this.refs['theInput'] );
    }
});

React.render(<Hello />, document.getElementById('container'));
1
votes

I'm not sure this is a good way but it works. Try it ! https://jsfiddle.net/qo3p3fh1/2/

<input type="text" ref={ function(component) { React.findDOMNode( component ).focus(); self.refs = {'theInput': component } } } />
1
votes

ES6 version

export default class Hello extends React.Component {
  componentDidMount() {
    // let textarea get focus when page loaded
    this.textArea.focus();
  }

  sendMessage(e) {
      console.log(this.textArea);
  }

  render() {
    return (    
      <textarea
        placeholder="say something..." ref={(ref) => {
          this.textArea = ref;
        }} onKeyPress={(e) => this.sendMessage(e)} autoComplete="off"
      >
      </textarea>
    );
  }
};
0
votes

Does the below code work for you?

var Hello = React.createClass({
    componentDidMount: function(){
       this.node.focus()
    },
    render: function() {
        return (
          <div>
            <input type="text" ref={node => this.node = node} />
            <input type="button" onClick={ this.submitForm } value="Submit!" />
          </div>
        );
    },
    submitForm: function() {
      console.log(this.node);
    }
});

React.render(<Hello />, document.getElementById('container'));

A good read, Why not to use findDOMNode()