Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to call dom element methods like focus() without using a ref? (Stateless Component Functions)

Tags:

reactjs

I try to use refs as least often as possible, but it seems there's no way around it for calling native dom methods (focus(), reset(), blur() etc) so I'm okay with that. Except, that I'd like to use the new stateless component functions for such basic things as form inputs, which as it stands, these stateless components do not allow refs pointing to them (they will return null). I understand that I can add a regular React class component wrapper around the stateless component to allow for ReactDOM.findDOMNode(ref) to work correctly, but what's the point of having the stateless function if it always has to be wrapped? Am I missing something?

like image 787
Balls McHenry Avatar asked Jul 29 '16 17:07

Balls McHenry


Video Answer


2 Answers

Here's a solution that I came up with that doesn't require wrapping the stateless component in a class. Instead it involves the parent passing a function to the stateless component as a prop that is used as the callback function for the ref on the DOM element.

First set a method on the stateful parent that will be used as a callback to the ref, and another method for doing the action on the DOM element (in this case focusing after a key press). Then send the method to the stateless child as a prop.

// note: Facebook now recommends using native js classes instead of React.createClass().
// note 2: You may need Babel to transpile some of ES6 syntax in use here.

const StatefulParent = React.createClass({
  getInitialState() {
    return {
      // doesn't matter for this example
    }
  },
  componentDidMount() {
    document.addEventListener('keyup', this.keyUp, false)
  },
  keyUp() {
    // calls the DOM focus method on the input when the 'tab' key is pressed
    if (e.keyCode === 9) this._input.focus()
  },
  inputSetter(ref) {
    this._input = ref
  },
  render() {
    <StatelessTextInput {...this.state} refCallback={this.inputSetter} />
  }
})

The stateless component assumes a method will be passed to it from the parent called refCallback. This prop can be passed down any number of component generations to reach the DOM element.

const StatelessTextInput = ({refCallback, ...props}) => (
  <input {...props} ref={refCallback} />
)
like image 200
Balls McHenry Avatar answered Jan 03 '23 13:01

Balls McHenry


Just wrap your stateless component with class component (es6) an attach ref. It's written in the official docs

like image 43
andreo Avatar answered Jan 03 '23 11:01

andreo