chevin99
chevin99

Reputation: 5088

How to focus a react-router Link

I have an input box used for searching, and want to be able to press the down key to move focus from the input to the first of a list of <Link>s. It seems what I have here won't work, since <Link> isn't an actual DOM node. I am able to get it to work using <a> instead of <Link> though.

let Link = require('react-router').Link

let SearchAndSelect = React.createClass({
  handleKeyPress: function (e) {
    if (e.keyCode === 40) { //'down' key
      this.refs['searchBox'].blur()
      this.refs['link0'].focus()
    }
  },

  render: function () {
    let ids = ['1', '2' , '3']

    return (
      <div>
        <input onKeyDown={this.handleKeyPress} ref="searchBox"/>

        <div>
          {ids.map((id, key) => (
            <Link to={`thing/${id}`}
              ref={`link${key}`}>
              {id}
            </Link>        
          ))}
        </div>
      </div>
    )
  }
})

Is there a way to use focus() with a react-router <Link>?

Upvotes: 3

Views: 7164

Answers (3)

mattGreenfield
mattGreenfield

Reputation: 161

To add a ref to the <a> rather than the Link component, you can use the React Router innerRef prop.

Something like <Link to={`thing/${id}`} innerRef={`link${key}`} >...

The docs are here: https://reacttraining.com/react-router/web/api/Link/innerref-function

Upvotes: 0

Robin Venneman
Robin Venneman

Reputation: 393

If you use ReactDOM.findDOMNode(this.refs['link0']).focus() it should work.

Upvotes: 2

finalfreq
finalfreq

Reputation: 6980

I didn't find a real direct way to do this but one thing you can do is:

<div ref={`link${key}`}>
  <Link to={`thing/${id}`}
    {id}
  </Link>    
</div>

wrap your link in a div and then put the ref on the div itself. Link returns an <a> tag with props attached.

 if (e.keyCode === 40) { //'down' key
    this.refs['searchBox'].blur()
    this.refs['link0'].children[0].focus()
  }

when you access the div ref you can just use .children[0] which will grab the a tag. This is a hacky approach and relies on react router Link always just rendering an a tag, but it will get you what you want.

Upvotes: 0

Related Questions