Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions UPGRADE_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,22 @@ they refer to.
0.5.x -> 0.6.x
--------------

### Link params

Links should now pass their params in the `params` property, though the
old behavior will still work, you should update your code soon because
it will be removed by `v1.0`

```js
// 0.5.x
<Link to="user" userId="123"/>

// 0.6.x
<Link to="user" params={{userId: "123"}}/>
```

### Dynamic Segments, keys, and lifecycle methods

If you have dynamic segments and are depending on `getInitialState`,
`componentWillMount`, or `componentDidMount` to fire between transitions
to the same route--like `users/123` and `users/456`, then you have two
Expand Down
26 changes: 19 additions & 7 deletions docs/api/components/Link.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,28 @@ Props

The name of the route to link to, or a full URL.

### `params`

Object, the parameters to fill in the dynamic segments of your route.

#### Example

```js
// given a route config like this
<Route name="user" path="/user/:userId"/>

// create a link with this
<Link to="user" params={{userId: "123"}}/>

// though, if your user properties match up to the dynamic segements:
<Link to="user" params={user}/>
```

### `query`

Object, Query parameters to add to the link. Access query parameters in
your route handler with `this.props.query`.

### `[param]`

Any dynamic segments the route defines (like `:userId`) are passed by
name through the link's properties to the resulting url.

### `activeClassName`

The className a `Link` receives when it's route is active. Defaults to
Expand All @@ -44,7 +56,7 @@ Example
Given a route like `<Route name="user" path="/users/:userId"/>`:

```xml
<Link to="user" userId={user.id} query={{foo: bar}}>{user.name}</Link>
<Link to="user" params={{userId: user.id}} query={{foo: bar}}>{user.name}</Link>
<!-- becomes one of these depending on your router and if the route is
active -->
<a href="/users/123?foo=bar" class="active">Michael</a>
Expand All @@ -54,6 +66,6 @@ active -->
<Link to="/users/123?foo=bar">{user.name}</Link>

<!-- change the activeClassName -->
<Link activeClassName="current" to="user" userId={user.id}>{user.name}</Link>
<Link activeClassName="current" to="user" params={{userId: user.id}}>{user.name}</Link>
```

4 changes: 2 additions & 2 deletions examples/animations/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ var App = React.createClass({
return (
<div>
<ul>
<li><Link to="image" service="kitten">Kitten</Link></li>
<li><Link to="image" service="cage">Cage</Link></li>
<li><Link to="image" params={{service: "kitten"}}>Kitten</Link></li>
<li><Link to="image" params={{service: "cage"}}>Cage</Link></li>
</ul>
<Transition transitionName="example">
{this.props.activeRouteHandler()}
Expand Down
2 changes: 1 addition & 1 deletion examples/data-flow/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ var App = React.createClass({

render: function() {
var links = this.state.tacos.map(function(taco) {
return <li><Link to="taco" name={taco.name}>{taco.name}</Link></li>
return <li><Link to="taco" params={taco}>{taco.name}</Link></li>
});
return (
<div className="App">
Expand Down
8 changes: 4 additions & 4 deletions examples/dynamic-segments/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ var App = React.createClass({
return (
<div>
<ul>
<li><Link to="user" userId="123">Bob</Link></li>
<li><Link to="user" userId="abc">Sally</Link></li>
<li><Link to="user" params={{userId: "123"}}>Bob</Link></li>
<li><Link to="user" params={{userId: "abc"}}>Sally</Link></li>
</ul>
{this.props.activeRouteHandler()}
</div>
Expand All @@ -26,8 +26,8 @@ var User = React.createClass({
<div className="User">
<h1>User id: {this.props.params.userId}</h1>
<ul>
<li><Link to="task" userId={this.props.params.userId} taskId="foo">foo task</Link></li>
<li><Link to="task" userId={this.props.params.userId} taskId="bar">bar task</Link></li>
<li><Link to="task" params={{userId: this.props.params.userId, taskId: "foo"}}>foo task</Link></li>
<li><Link to="task" params={{userId: this.props.params.userId, taskId: "bar"}}>bar task</Link></li>
</ul>
{this.props.activeRouteHandler()}
</div>
Expand Down
2 changes: 1 addition & 1 deletion examples/master-detail/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ var App = React.createClass({

render: function() {
var contacts = this.state.contacts.map(function(contact) {
return <li key={contact.id}><Link to="contact" id={contact.id}>{contact.first}</Link></li>
return <li key={contact.id}><Link to="contact" params={contact}>{contact.first}</Link></li>
});
return (
<div className="App">
Expand Down
6 changes: 3 additions & 3 deletions examples/query-params/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ var App = React.createClass({
return (
<div>
<ul>
<li><Link to="user" userId="123">Bob</Link></li>
<li><Link to="user" userId="123" query={{showAge: true}}>Bob With Query Params</Link></li>
<li><Link to="user" userId="abc">Sally</Link></li>
<li><Link to="user" params={{userId: "123"}}>Bob</Link></li>
<li><Link to="user" params={{userId: "123"}} query={{showAge: true}}>Bob With Query Params</Link></li>
<li><Link to="user" params={{userId: "abc"}}>Sally</Link></li>
</ul>
{this.props.activeRouteHandler()}
</div>
Expand Down
36 changes: 22 additions & 14 deletions modules/components/Link.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var withoutProperties = require('../helpers/withoutProperties');
var transitionTo = require('../helpers/transitionTo');
var hasOwnProperty = require('../helpers/hasOwnProperty');
var makeHref = require('../helpers/makeHref');
var warning = require('react/lib/warning');

function isLeftClickEvent(event) {
return event.button === 0;
Expand All @@ -14,7 +15,7 @@ function isModifiedEvent(event) {
}

/**
* A map of <Link> component props that are reserved for use by the
* DEPRECATED: A map of <Link> component props that are reserved for use by the
* router and/or React. All other props are used as params that are
* interpolated into the link's path.
*/
Expand All @@ -38,12 +39,12 @@ var RESERVED_PROPS = {
*
* You could use the following component to link to that route:
*
* <Link to="showPost" postId="123"/>
* <Link to="showPost" params={{postId: "123"}} />
*
* In addition to params, links may pass along query string parameters
* using the `query` prop.
*
* <Link to="showPost" postId="123" query={{show:true}}/>
* <Link to="showPost" params={{postId: "123"}} query={{show:true}}/>
*/
var Link = React.createClass({

Expand All @@ -53,15 +54,29 @@ var Link = React.createClass({

statics: {

// TODO: Deprecate passing props as params in v1.0
getUnreservedProps: function (props) {
warning(
false,
'Passing props for params on <Link>s is deprecated, '+
'please use the `params` property.'
);
return withoutProperties(props, RESERVED_PROPS);
},

/**
* Returns a hash of URL parameters to use in this <Link>'s path.
*/
getParams: function (props) {
return props.params || Link.getUnreservedProps(props);
}

},

propTypes: {
to: React.PropTypes.string.isRequired,
activeClassName: React.PropTypes.string.isRequired,
params: React.PropTypes.object,
query: React.PropTypes.object,
onClick: React.PropTypes.func
},
Expand All @@ -78,18 +93,11 @@ var Link = React.createClass({
};
},

/**
* Returns a hash of URL parameters to use in this <Link>'s path.
*/
getParams: function () {
return Link.getUnreservedProps(this.props);
},

/**
* Returns the value of the "href" attribute to use on the DOM element.
*/
getHref: function () {
return makeHref(this.props.to, this.getParams(), this.props.query);
return makeHref(this.props.to, Link.getParams(this.props), this.props.query);
},

/**
Expand All @@ -106,7 +114,7 @@ var Link = React.createClass({
},

componentWillReceiveProps: function (nextProps) {
var params = Link.getUnreservedProps(nextProps);
var params = Link.getParams(nextProps);

this.setState({
isActive: Link.isActive(nextProps.to, params, nextProps.query)
Expand All @@ -115,7 +123,7 @@ var Link = React.createClass({

updateActiveState: function () {
this.setState({
isActive: Link.isActive(this.props.to, this.getParams(), this.props.query)
isActive: Link.isActive(this.props.to, Link.getParams(this.props), this.props.query)
});
},

Expand All @@ -135,7 +143,7 @@ var Link = React.createClass({
event.preventDefault();

if (allowTransition)
transitionTo(this.props.to, this.getParams(), this.props.query);
transitionTo(this.props.to, Link.getParams(this.props), this.props.query);
},

render: function () {
Expand Down