Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cleaner way to change focus on child components in React

Tags:

focus

reactjs

I'm trying to figure out a cleaner way to use arrow keys to move focus up and down in a list of inputs using React. The list is the parent component, the input the children. In order to figure out what input should be focused next, I'm giving each child a ref as well as a numeric id that I use to track ordering. When an arrow key is detected, the callback then finds the child with the correct ref and goes into that child's refs to grab the input and give it focus.

I'm new at React, this feels quite dirty, thus I'm wondering if there's a cleaner solution.

Code and working jsfiddle:

var Child = React.createClass({
    handleUp: function(e) {
        switch(e.key) {
            case "ArrowDown":
                this.props.handleFocus(this.props.id+1);
            break;
            case "ArrowUp":
                this.props.handleFocus(this.props.id-1);            
            break;
        }
    },
    render: function() {
        return <div><input defaultValue={this.props.name} onKeyUp={this.handleUp} ref="input" /></div>;
    }
});

var Parent = React.createClass({
    handleFocus: function(id) {
        var child = this.refs['child' + id];
        if (!child) return;
        var input = child.refs.input;
        input.getDOMNode().focus();
    },
    render: function() {
        var inputs = [];
        for (var i=0; i<10; i++) {
            inputs.push(<Child key={i} id={i} name={"value" + i} handleFocus={this.handleFocus} ref={'child' + i} />);
        }
        return <div>
            {inputs}
        </div>;
    }
});

http://jsfiddle.net/69z2wepo/509/

like image 245
mikhuang Avatar asked Dec 30 '14 19:12

mikhuang


1 Answers

There are a few ways to do this, but none are really 'better' than this.

The alternatives would use a mixin, but that brings in the mental cost of black box abstraction for little gain. I'd just keep it as is.

like image 166
Brigand Avatar answered Oct 19 '22 01:10

Brigand