Skip to content

Commit

Permalink
Accessing <Link>'s underlying node via innerRef (#5294)
Browse files Browse the repository at this point in the history
* Accessing <Link>s underlying node via `innerRef`

Use case: [`react-measure`](https://github.com/souporserious/react-measure):

I'd like to show a tooltip above a Link. For this I need to know the underlying DOM node's position. Proxying the `ref` via an `innerRef`-prop would allow to do this. (I stole the naming from [`glamorous`](https://github.com/paypal/glamorous#innerref))

This would allow to extract the position like this:

```jsx
<Measure bounds>{({measureRef}) => 
  <Link to="..." innerRef={measureRef}/>
}</Measure>
```

Happy to adapt docs in this PR if you think this is worthwhile :)

* add test case for Link’s innerRef

* add innerRef to Link’s api docs
  • Loading branch information
danielberndt authored and timdorr committed Jun 28, 2017
1 parent 920af5b commit 81c5a02
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 2 deletions.
13 changes: 13 additions & 0 deletions packages/react-router-dom/docs/api/Link.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,16 @@ When `true`, clicking the link will replace the current entry in the history sta
```js
<Link to="/courses" replace />
```

## innerRef: function

Allows access to the underlying `ref` of the component

```js

const refCallback = node => {
// `node` refers to the mounted DOM element or null when unmounted
}

<Link to="/" innerRef={refCallback} />
```
4 changes: 2 additions & 2 deletions packages/react-router-dom/modules/Link.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ class Link extends React.Component {
}

render() {
const { replace, to, ...props } = this.props // eslint-disable-line no-unused-vars
const { replace, to, innerRef, ...props } = this.props // eslint-disable-line no-unused-vars

const href = this.context.router.history.createHref(
typeof to === 'string' ? { pathname: to } : to
)

return <a {...props} onClick={this.handleClick} href={href}/>
return <a {...props} onClick={this.handleClick} href={href} ref={innerRef}/>
}
}

Expand Down
16 changes: 16 additions & 0 deletions packages/react-router-dom/modules/__tests__/Link-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,22 @@ describe('A <Link>', () => {

expect(href).toEqual('/the/path?the=query#the-hash')
})

it('exposes its ref via an innerRef prop', done => {
const node = document.createElement('div')

const refCallback = n => {
expect(n.tagName).toEqual('A')
done()
}

ReactDOM.render(
<MemoryRouter>
<Link to="/" innerRef={refCallback}>link</Link>
</MemoryRouter>,
node
)
})
})

describe('When a <Link> is clicked', () => {
Expand Down

0 comments on commit 81c5a02

Please sign in to comment.