Skip to content

Commit

Permalink
[changed] Deprecate Navigation/State mixins
Browse files Browse the repository at this point in the history
Fixes #835
Fixes #744
  • Loading branch information
mjackson committed Feb 24, 2015
1 parent b8f1600 commit 61f0a8c
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 238 deletions.
52 changes: 30 additions & 22 deletions modules/Navigation.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
var warning = require('react/lib/warning');
var PropTypes = require('./PropTypes');

function deprecatedMethod(routerMethodName, fn) {
return function () {
warning(
false,
`Router.Navigation is deprecated. Please use this.context.router.${routerMethodName}() instead`
);

return fn.apply(this, arguments);
};
}

/**
* A mixin for components that modify the URL.
*
* Example:
*
* var MyLink = React.createClass({
* mixins: [ Router.Navigation ],
* handleClick: function (event) {
* handleClick(event) {
* event.preventDefault();
* this.transitionTo('aRoute', { the: 'params' }, { the: 'query' });
* },
* render: function () {
* render() {
* return (
* <a onClick={this.handleClick}>Click me!</a>
* );
Expand All @@ -21,51 +33,47 @@ var PropTypes = require('./PropTypes');
var Navigation = {

contextTypes: {
makePath: PropTypes.func.isRequired,
makeHref: PropTypes.func.isRequired,
transitionTo: PropTypes.func.isRequired,
replaceWith: PropTypes.func.isRequired,
goBack: PropTypes.func.isRequired
router: PropTypes.router.isRequired
},

/**
* Returns an absolute URL path created from the given route
* name, URL parameters, and query values.
*/
makePath: function (to, params, query) {
return this.context.makePath(to, params, query);
},
makePath: deprecatedMethod('makePath', function (to, params, query) {
return this.context.router.makePath(to, params, query);
}),

/**
* Returns a string that may safely be used as the href of a
* link to the route with the given name.
*/
makeHref: function (to, params, query) {
return this.context.makeHref(to, params, query);
},
makeHref: deprecatedMethod('makeHref', function (to, params, query) {
return this.context.router.makeHref(to, params, query);
}),

/**
* Transitions to the URL specified in the arguments by pushing
* a new URL onto the history stack.
*/
transitionTo: function (to, params, query) {
this.context.transitionTo(to, params, query);
},
transitionTo: deprecatedMethod('transitionTo', function (to, params, query) {
this.context.router.transitionTo(to, params, query);
}),

/**
* Transitions to the URL specified in the arguments by replacing
* the current URL in the history stack.
*/
replaceWith: function (to, params, query) {
this.context.replaceWith(to, params, query);
},
replaceWith: deprecatedMethod('replaceWith', function (to, params, query) {
this.context.router.replaceWith(to, params, query);
}),

/**
* Transitions to the previous URL.
*/
goBack: function () {
return this.context.goBack();
}
goBack: deprecatedMethod('goBack', function () {
return this.context.router.goBack();
})

};

Expand Down
28 changes: 0 additions & 28 deletions modules/NavigationContext.js

This file was deleted.

22 changes: 17 additions & 5 deletions modules/PropTypes.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
var assign = require('react/lib/Object.assign');
var ReactPropTypes = require('react').PropTypes;
var Route = require('./Route');

var PropTypes = assign({
var PropTypes = assign({}, ReactPropTypes, {

/**
* Requires that the value of a prop be falsy.
* Indicates that a prop should be falsy.
*/
falsy(props, propName, componentName) {
if (props[propName])
return new Error('<' + componentName + '> may not have a "' + propName + '" prop');
}
return new Error(`<${componentName}> may not have a "${propName}" prop`);
},

}, ReactPropTypes);
/**
* Indicates that a prop should be a Route object.
*/
route: ReactPropTypes.instanceOf(Route),

/**
* Indicates that a prop should be a Router object.
*/
//router: ReactPropTypes.instanceOf(Router) // TODO
router: ReactPropTypes.func

});

module.exports = PropTypes;
9 changes: 4 additions & 5 deletions modules/RouteHandlerMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ var REF_NAME = '__routeHandler__';
var RouteHandlerMixin = {

contextTypes: {
getRouteAtDepth: PropTypes.func.isRequired,
setRouteComponentAtDepth: PropTypes.func.isRequired,
routeHandlers: PropTypes.array.isRequired
routeHandlers: PropTypes.array.isRequired,
router: PropTypes.router.isRequired
},

childContextTypes: {
Expand All @@ -35,15 +34,15 @@ var RouteHandlerMixin = {
},

_updateRouteComponent: function (component) {
this.context.setRouteComponentAtDepth(this.getRouteDepth(), component);
this.context.router.setRouteComponentAtDepth(this.getRouteDepth(), component);
},

getRouteDepth: function () {
return this.context.routeHandlers.length;
},

createChildRouteHandler: function (props) {
var route = this.context.getRouteAtDepth(this.getRouteDepth());
var route = this.context.router.getRouteAtDepth(this.getRouteDepth());
return route ? React.createElement(route.handler, assign({}, props || this.props, { ref: REF_NAME })) : null;
}

Expand Down
65 changes: 36 additions & 29 deletions modules/State.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
var warning = require('react/lib/warning');
var PropTypes = require('./PropTypes');

function deprecatedMethod(routerMethodName, fn) {
return function () {
warning(
false,
`Router.State is deprecated. Please use this.context.router.${routerMethodName}() instead`
);

return fn.apply(this, arguments);
};
}

/**
* A mixin for components that need to know the path, routes, URL
* params and query that are currently active.
Expand All @@ -8,7 +20,7 @@ var PropTypes = require('./PropTypes');
*
* var AboutLink = React.createClass({
* mixins: [ Router.State ],
* render: function () {
* render() {
* var className = this.props.className;
*
* if (this.isActive('about'))
Expand All @@ -21,56 +33,51 @@ var PropTypes = require('./PropTypes');
var State = {

contextTypes: {
getCurrentPath: PropTypes.func.isRequired,
getCurrentRoutes: PropTypes.func.isRequired,
getCurrentPathname: PropTypes.func.isRequired,
getCurrentParams: PropTypes.func.isRequired,
getCurrentQuery: PropTypes.func.isRequired,
isActive: PropTypes.func.isRequired
router: PropTypes.router.isRequired
},

/**
* Returns the current URL path.
*/
getPath: function () {
return this.context.getCurrentPath();
},

/**
* Returns an array of the routes that are currently active.
*/
getRoutes: function () {
return this.context.getCurrentRoutes();
},
getPath: deprecatedMethod('getCurrentPath', function () {
return this.context.router.getCurrentPath();
}),

/**
* Returns the current URL path without the query string.
*/
getPathname: function () {
return this.context.getCurrentPathname();
},
getPathname: deprecatedMethod('getCurrentPathname', function () {
return this.context.router.getCurrentPathname();
}),

/**
* Returns an object of the URL params that are currently active.
*/
getParams: function () {
return this.context.getCurrentParams();
},
getParams: deprecatedMethod('getCurrentParams', function () {
return this.context.router.getCurrentParams();
}),

/**
* Returns an object of the query params that are currently active.
*/
getQuery: function () {
return this.context.getCurrentQuery();
},
getQuery: deprecatedMethod('getCurrentQuery', function () {
return this.context.router.getCurrentQuery();
}),

/**
* Returns an array of the routes that are currently active.
*/
getRoutes: deprecatedMethod('getCurrentRoutes', function () {
return this.context.router.getCurrentRoutes();
}),

/**
* A helper method to determine if a given route, params, and query
* are active.
*/
isActive: function (to, params, query) {
return this.context.isActive(to, params, query);
}
isActive: deprecatedMethod('isActive', function (to, params, query) {
return this.context.router.isActive(to, params, query);
})

};

Expand Down
Loading

3 comments on commit 61f0a8c

@ericclemmons
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, great work @mjackson!

@mjackson
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ericclemmons Thanks! :)

@gaearon
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome.

Please sign in to comment.