101 lines
2.5 KiB
Markdown
101 lines
2.5 KiB
Markdown
# Navigating Programatically
|
|
|
|
While most navigation happens with `Link`, you can programatically
|
|
navigate around an application in response to form submissions, button
|
|
clicks, etc.
|
|
|
|
Let's make a little form in `Repos` that programatically navigates.
|
|
|
|
```js
|
|
// modules/Repos.js
|
|
import React from 'react'
|
|
import NavLink from './NavLink'
|
|
|
|
export default React.createClass({
|
|
|
|
// add this method
|
|
handleSubmit(event) {
|
|
event.preventDefault()
|
|
const userName = event.target.elements[0].value
|
|
const repo = event.target.elements[1].value
|
|
const path = `/repos/${userName}/${repo}`
|
|
console.log(path)
|
|
},
|
|
|
|
render() {
|
|
return (
|
|
<div>
|
|
<h2>Repos</h2>
|
|
<ul>
|
|
<li><NavLink to="/repos/reactjs/react-router">React Router</NavLink></li>
|
|
<li><NavLink to="/repos/facebook/react">React</NavLink></li>
|
|
{/* add this form */}
|
|
<li>
|
|
<form onSubmit={this.handleSubmit}>
|
|
<input type="text" placeholder="userName"/> / {' '}
|
|
<input type="text" placeholder="repo"/>{' '}
|
|
<button type="submit">Go</button>
|
|
</form>
|
|
</li>
|
|
</ul>
|
|
{this.props.children}
|
|
</div>
|
|
)
|
|
}
|
|
})
|
|
```
|
|
|
|
There are two ways you can do this, the first is simpler than the
|
|
second.
|
|
|
|
First we can use the `browserHistory` singleton that we passed into
|
|
`Router` in `index.js` and push a new url into the history.
|
|
|
|
```js
|
|
// Repos.js
|
|
import { browserHistory } from 'react-router'
|
|
|
|
// ...
|
|
handleSubmit(event) {
|
|
// ...
|
|
const path = `/repos/${userName}/${repo}`
|
|
browserHistory.push(path)
|
|
},
|
|
// ...
|
|
```
|
|
|
|
There's a potential problem with this though. If you pass a different
|
|
history to `Router` than you use here, it won't work. It's not very
|
|
common to use anything other than `browserHistory`, so this is
|
|
acceptable practice. If you're concerned about it, you can make a module
|
|
that exports the history you want to use across the app, or...
|
|
|
|
You can also use the `router` that `Router` provides on "context".
|
|
First, you ask for context in the component, and then you can use it:
|
|
|
|
```js
|
|
export default React.createClass({
|
|
|
|
// ask for `router` from context
|
|
contextTypes: {
|
|
router: React.PropTypes.object
|
|
},
|
|
|
|
// ...
|
|
|
|
handleSubmit(event) {
|
|
// ...
|
|
this.context.router.push(path)
|
|
},
|
|
|
|
// ..
|
|
})
|
|
```
|
|
|
|
This way you'll be sure to be pushing to whatever history gets passed to
|
|
`Router`. It also makes testing a bit easier since you can more easily
|
|
stub context than singletons.
|
|
|
|
---
|
|
|
|
[Next: Server Rendering](../13-server-rendering/)
|