Skip to content
This repository has been archived by the owner on May 23, 2018. It is now read-only.

Commit

Permalink
feat: split Link into LinkBase component and withRoute higher-order c…
Browse files Browse the repository at this point in the history
…omponent
  • Loading branch information
troch committed Jan 16, 2016
1 parent 9d74726 commit 81e22ad
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 28 deletions.
33 changes: 9 additions & 24 deletions modules/Link.js → modules/BaseLink.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React, { Component, PropTypes } from 'react';

class Link extends Component {
class BaseLink extends Component {
constructor(props, context) {
super(props, context);
this.router = context.router;

this.isActive = this.isActive.bind(this);
this.clickHandler = this.clickHandler.bind(this);
Expand All @@ -13,7 +12,7 @@ class Link extends Component {
}

isActive() {
return this.router.isActive(this.props.routeName, this.props.routeParams);
return this.props.router.isActive(this.props.routeName, this.props.routeParams);
}

clickHandler(evt) {
Expand All @@ -29,27 +28,15 @@ class Link extends Component {

if (evt.button === 0 && !comboKey) {
evt.preventDefault();
this.router.navigate(this.props.routeName, this.props.routeParams, this.props.routeOptions);
this.props.router.navigate(this.props.routeName, this.props.routeParams, this.props.routeOptions);
}
}

routeChangeHandler(toState, fromState) {
this.setState({active: this.isActive()});
}

componentDidMount() {
this.router.addListener(this.routeChangeHandler);
}

componentWillUnmount() {
this.router.removeListener(this.routeChangeHandler);
}

render() {
const { routeName, routeParams, className, activeClassName, children } = this.props;
const { active } = this.state;
const { router, routeName, routeParams, className, activeClassName, children } = this.props;

const href = this.router.buildUrl(routeName, routeParams);
const active = this.isActive();
const href = router.buildUrl(routeName, routeParams);
const linkclassName = (className ? className.split(' ') : [])
.concat(active ? [activeClassName] : []).join(' ');

Expand All @@ -59,11 +46,9 @@ class Link extends Component {
}
}

Link.contextTypes = {
router: PropTypes.object.isRequired
};

Link.propTypes = {
// route: PropTypes.object.isRequired,
router: PropTypes.object.isRequired,
routeName: PropTypes.string.isRequired,
routeParams: PropTypes.object,
routeOptions: PropTypes.object,
Expand All @@ -79,4 +64,4 @@ Link.defaultProps = {
routeOptions: {}
};

export default Link;
export default BaseLink;
13 changes: 9 additions & 4 deletions modules/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import Link from './Link';
import BaseLink from './BaseLink';
import routeNode from './routeNode';
import RouterProvider from './RouterProvider';
import withRoute from './withRoute';

export default {
Link,
const Link = withRoute(BaseLink);

export {
BaseLink,
routeNode,
RouterProvider
RouterProvider,
withRoute,
Link
};
42 changes: 42 additions & 0 deletions modules/withRoute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Component, createElement } from 'react';
import * as invariant from 'invariant';

function withRoute(BaseComponent) {
class ComponentWithRoute extends Component {
constructor(props, context) {
super(props, context);
this.router = context.router;
this.state = {
previousRoute: null,
route: this.router.getState()
};
}

componentDidMount() {
invariant(
this.router.registeredPlugins.LISTENERS,
'[react-router5] missing plugin router5-listeners.'
);

this.listener = (toState, fromState) => this.setState({ previousRoute: fromState, route: toState });
this.router.addListener(this.nodeListener);
}

componentWillUnmout() {
this.router.removeListener(this.listener);
}

render() {
invariant(
!props.router && !props.route && !props.previousRoute,
'[react-router5] prop names `router`, `route` and `previousRoute` are reserved.'
);

return createElement(BaseComponent, { ...props, ...this.state, router: this.router });
}
}

return ComponentWithRoute;
}

export default withRoute;

0 comments on commit 81e22ad

Please sign in to comment.