Skip to content

Commit a96a042

Browse files
committed
Directly consume context in Link.
1 parent c70e4f3 commit a96a042

File tree

3 files changed

+27
-40
lines changed

3 files changed

+27
-40
lines changed

packages/react-router-dom/modules/Link.js

Lines changed: 23 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,20 @@ const isModifiedEvent = event =>
1010
/**
1111
* The public API for rendering a history-aware <a>.
1212
*/
13-
class InnerLink extends React.Component {
13+
class Link extends React.Component {
1414
static propTypes = {
1515
onClick: PropTypes.func,
1616
target: PropTypes.string,
1717
replace: PropTypes.bool,
1818
to: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired,
19-
innerRef: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
20-
router: PropTypes.shape({
21-
history: PropTypes.shape({
22-
push: PropTypes.func.isRequired,
23-
replace: PropTypes.func.isRequired,
24-
createHref: PropTypes.func.isRequired
25-
}).isRequired
26-
}).isRequired
19+
innerRef: PropTypes.oneOfType([PropTypes.string, PropTypes.func])
2720
};
2821

2922
static defaultProps = {
3023
replace: false
3124
};
3225

33-
handleClick = event => {
26+
handleClick = history => event => {
3427
if (this.props.onClick) this.props.onClick(event);
3528

3629
if (
@@ -41,7 +34,7 @@ class InnerLink extends React.Component {
4134
) {
4235
event.preventDefault();
4336

44-
const { replace, to, router: { history } } = this.props;
37+
const { replace, to } = this.props;
4538

4639
if (replace) {
4740
history.replace(to);
@@ -52,33 +45,30 @@ class InnerLink extends React.Component {
5245
};
5346

5447
render() {
55-
const { replace, to, innerRef, router, ...props } = this.props; // eslint-disable-line no-unused-vars
56-
57-
invariant(
58-
this.props.router,
59-
"You should not use <Link> outside a <Router>"
60-
);
48+
const { replace, to, innerRef, ...props } = this.props; // eslint-disable-line no-unused-vars
6149

6250
invariant(to !== undefined, 'You must specify the "to" property');
6351

64-
const { history } = router;
65-
const location =
66-
typeof to === "string"
67-
? createLocation(to, null, null, history.location)
68-
: to;
52+
return RouterContext.consume(({ router }) => {
53+
invariant(router, "You should not use <Link> outside a <Router>");
54+
55+
const { history } = router;
56+
const location =
57+
typeof to === "string"
58+
? createLocation(to, null, null, history.location)
59+
: to;
6960

70-
const href = history.createHref(location);
71-
return (
72-
<a {...props} onClick={this.handleClick} href={href} ref={innerRef} />
73-
);
61+
const href = history.createHref(location);
62+
return (
63+
<a
64+
{...props}
65+
onClick={this.handleClick(history)}
66+
href={href}
67+
ref={innerRef}
68+
/>
69+
);
70+
});
7471
}
7572
}
7673

77-
export { InnerLink };
78-
79-
const Link = props =>
80-
RouterContext.consume(({ router }) => (
81-
<InnerLink {...props} router={router} />
82-
));
83-
8474
export default Link;

packages/react-router-dom/modules/NavLink.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from "react";
22
import PropTypes from "prop-types";
33
import Route from "./Route";
4-
import Link, { InnerLink } from "./Link";
4+
import Link from "./Link";
55

66
/**
77
* A <Link> wrapper that knows if it's "active" or not.
@@ -52,7 +52,7 @@ const NavLink = ({
5252
};
5353

5454
NavLink.propTypes = {
55-
to: InnerLink.propTypes.to,
55+
to: Link.propTypes.to,
5656
exact: PropTypes.bool,
5757
strict: PropTypes.bool,
5858
location: PropTypes.object,

packages/react-router-dom/modules/__tests__/Link-test.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,7 @@ describe("A <Link>", () => {
5151
ReactDOM.render(<Link to="/">link</Link>, node);
5252
}).toThrow(/You should not use <Link> outside a <Router>/);
5353

54-
expect(console.error.calls.count()).toBe(3);
55-
expect(console.error.calls.argsFor(0)[0]).toContain(
56-
"The prop `router` is marked as required in `InnerLink`"
57-
);
54+
expect(console.error.calls.count()).toBe(2);
5855
});
5956

6057
it('throws with no "to" prop', () => {
@@ -73,7 +70,7 @@ describe("A <Link>", () => {
7370

7471
expect(console.error.calls.count()).toBe(3);
7572
expect(console.error.calls.argsFor(0)[0]).toContain(
76-
"The prop `to` is marked as required in `InnerLink`"
73+
"The prop `to` is marked as required in `Link`"
7774
);
7875
});
7976

0 commit comments

Comments
 (0)