Skip to content

Commit 4eee7da

Browse files
pshrmnryanflorence
authored andcommitted
Links apathetic to active don't subscribe (#3985) (#3986)
* Links apathetic to active don't subscribe * add tests to check if Link subscribes
1 parent d041434 commit 4eee7da

File tree

2 files changed

+89
-15
lines changed

2 files changed

+89
-15
lines changed

modules/Link.js

+32-14
Original file line numberDiff line numberDiff line change
@@ -51,23 +51,41 @@ class Link extends React.Component {
5151
}
5252

5353
render() {
54+
const { router } = this.context
55+
const {
56+
to,
57+
style,
58+
activeStyle,
59+
className,
60+
activeClassName,
61+
location: propLocation,
62+
isActive: getIsActive,
63+
activeOnlyWhenExact, // eslint-disable-line
64+
replace, // eslint-disable-line
65+
...rest
66+
} = this.props
67+
68+
// If there are no props that require location information
69+
// the LocationSubscriber is unnecessary.
70+
if (
71+
activeClassName === '' &&
72+
Object.keys(activeStyle).length === 0 &&
73+
typeof rest.children !== 'function'
74+
) {
75+
return (
76+
<a
77+
{...rest}
78+
href={router ? router.createHref(to) : to}
79+
onClick={this.handleClick}
80+
style={style}
81+
className={className}
82+
/>
83+
)
84+
}
85+
5486
return (
5587
<LocationSubscriber>
5688
{(contextLocation) => {
57-
const { router } = this.context
58-
const {
59-
to,
60-
style,
61-
activeStyle,
62-
className,
63-
activeClassName,
64-
location: propLocation,
65-
isActive: getIsActive,
66-
activeOnlyWhenExact, // eslint-disable-line
67-
replace, // eslint-disable-line
68-
...rest
69-
} = this.props
70-
7189
const currentLocation = propLocation || contextLocation
7290

7391
const isActive = getIsActive(

modules/__tests__/Link-test.js

+57-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import expect from 'expect'
1+
import expect, { spyOn, restoreSpies } from 'expect'
22
import React, { PropTypes } from 'react'
33
import Link from '../Link'
44
import { render } from 'react-dom'
55
import { LocationBroadcast } from '../Broadcasts'
6+
import * as broadcasters from '../Broadcasts'
67

78
describe('Link', () => {
89

@@ -287,4 +288,59 @@ describe('Link', () => {
287288
expect(a.className).toEqual('active')
288289
})
289290
})
291+
292+
describe('knowledge of location', () => {
293+
294+
beforeEach(() => {
295+
spyOn(broadcasters, 'LocationSubscriber').andCallThrough()
296+
})
297+
298+
afterEach(() => {
299+
restoreSpies()
300+
})
301+
302+
it('renders <LocationSubscriber> when it has an activeClassName', () => {
303+
const div = document.createElement('div')
304+
render((
305+
<Link
306+
to='/foo'
307+
activeClassName='active'
308+
location={{ pathname: '/bar' }}
309+
/>
310+
), div)
311+
expect(broadcasters.LocationSubscriber).toHaveBeenCalled()
312+
})
313+
314+
it('renders <LocationSubscriber> when it has an activeStyle', () => {
315+
const div = document.createElement('div')
316+
render((
317+
<Link
318+
to='/foo'
319+
activeStyle={{ color: 'red' }}
320+
location={{ pathname: '/bar' }}
321+
/>
322+
), div)
323+
expect(broadcasters.LocationSubscriber).toHaveBeenCalled()
324+
})
325+
326+
it('renders <LocationSubscriber> when props.children is a function', () => {
327+
const div = document.createElement('div')
328+
render((
329+
<Link to='/foo' location={{ pathname: '/bar' }}>
330+
{
331+
({isActive}) => <a className={isActive ? 'active' : ''}>Test!</a>
332+
}
333+
</Link>
334+
), div)
335+
expect(broadcasters.LocationSubscriber).toHaveBeenCalled()
336+
})
337+
338+
it('does not render <LocationSubscriber> when it has no active props', () => {
339+
const div = document.createElement('div')
340+
render((
341+
<Link to='/foo'>Foo</Link>
342+
), div)
343+
expect(broadcasters.LocationSubscriber).toNotHaveBeenCalled()
344+
})
345+
})
290346
})

0 commit comments

Comments
 (0)