对于任何一个前端框架都有页面跳转,而这个跳转就一定需要路由的定义,比如Angular,Durandal等等,今天我们学习一下如果定义个路由在React中。
为了便于理解,我们同样附上一段代码,看看究竟是如何实现的:
import React from 'react'
import { render,findDOMNode } from 'react-dom'
import {
browserHistory,Router,Route,IndexRoute,Link,withRouter
} from 'react-router'
import ContactStore from './ContactStore'
import './app.css'
const App = React.createClass({
getInitialState() {
return {
contacts: ContactStore.getContacts(),loading: true
}
},componentWillMount() {
ContactStore.init()
},componentDidMount() {
ContactStore.addChangeListener(this.updateContacts)
},componentWillUnmount() {
ContactStore.removeChangeListener(this.updateContacts)
},updateContacts() {
if (!this.isMounted())
return
this.setState({
contacts: ContactStore.getContacts(),loading: false
})
},render() {
const contacts = this.state.contacts.map(function (contact) {
return <li key={contact.id}><Link to={`/contact/${contact.id}`}>{contact.first}</Link></li>
})
return (
<div className="App">
<div className="ContactList">
<Link to="/contact/new">New Contact</Link>
<ul>
{contacts}
</ul>
</div>
<div className="Content">
{this.props.children}
</div>
</div>
)
}
})
const Index = React.createClass({
render() {
return <h1>Address Book</h1>
}
})
const Contact = withRouter(
React.createClass({
getStateFromStore(props) {
const { id } = props ? props.params : this.props.params
return {
contact: ContactStore.getContact(id)
}
},getInitialState() {
return this.getStateFromStore()
},componentDidMount() {
ContactStore.addChangeListener(this.updateContact)
},componentWillUnmount() {
ContactStore.removeChangeListener(this.updateContact)
},componentWillReceiveProps(nextProps) {
this.setState(this.getStateFromStore(nextProps))
},updateContact() {
if (!this.isMounted())
return
this.setState(this.getStateFromStore())
},destroy() {
const { id } = this.props.params
ContactStore.removeContact(id)
this.props.router.push('/')
},render() {
const contact = this.state.contact || {}
const name = contact.first + ' ' + contact.last
const avatar = contact.avatar || 'http://placecage.com/50/50'
return (
<div className="Contact">
<img height="50" src={avatar} key={avatar} />
<h3>{name}</h3>
<button onClick={this.destroy}>Delete</button>
</div>
)
}
})
)
const NewContact = withRouter(
React.createClass({
createContact(event) {
event.preventDefault()
ContactStore.addContact({
first: findDOMNode(this.refs.first).value,last: findDOMNode(this.refs.last).value
},(contact) => {
this.props.router.push(`/contact/${contact.id}`)
})
},render() {
return (
<form onSubmit={this.createContact}>
<p>
<input type="text" ref="first" placeholder="First name" />
<input type="text" ref="last" placeholder="Last name" />
</p>
<p>
<button type="submit">Save</button> <Link to="/">Cancel</Link>
</p>
</form>
)
}
})
)
const NotFound = React.createClass({
render() {
return <h2>Not found</h2>
}
})
render((
<Router history={browserHistory}>
<Route path="/" component={App}>
<IndexRoute component={Index} />
<Route path="contact/new" component={NewContact} />
<Route path="contact/:id" component={Contact} />
<Route path="*" component={NotFound} />
</Route>
</Router>
),document.getElementById('example'))
如果需要使用React-router,我们需要import router核心组件,如上:
import {
browserHistory,withRouter} from ‘react-router’;
我们下面具体分析一下:
- browserHistory: 主要用于浏览器历史缓存回退。
- Router: 用于我们定义路由的一个Component,一定记得写。
- Route: 一个项目我们会有很多路由@R_874_404@面,这是用来指定跳转路径和页面的。
- IndexRoute: 这个是路由的默认跳转,相当于angular-router的otherwise.
- Link: 这个相当于一个click 时间的component,可以配合将要跳转的路径。
- withRouter: 当我们定义一个route,需要指定一个component,这个component我们就可以用withRouter来定义啦。如上。
对于一个路由,我们肯定会想到,怎么能用路由传递一个数值呢,因为在项目中会多次用到,下面我们来看一段代码:
import React from 'react' import { render } from 'react-dom' import { browserHistory,Link } from 'react-router' const User = ({ params: { userID },location: { query } }) => { let age = query && query.showAge ? '33' : '' return ( <div className="User"> <h1>User id: {userID}</h1> {age} </div> ) } const App = ({ children }) => ( <div> <ul> <li><Link to="/user/bob" activeClassName="active">Bob</Link></li> <li><Link to={{ pathname: '/user/bob',query: { showAge: true } }} activeClassName="active">Bob With Query Params</Link></li> <li><Link to="/user/sally" activeClassName="active">Sally</Link></li> </ul> {children} </div> ) render(( <Router history={browserHistory}> <Route path="/" component={App}> <Route path="user/:userID" component={User} /> </Route> </Router> ),document.getElementById('example'))
其实React路由传值和Angular是非常相像的,比如 path=”user/:userID” ,其中userID就是我们要传递的参数。
获取这个参数也很简单,只需要 params: { userID } 即可。
前面我们讲到,通过Link配置我们将要跳转的页面,Link同样提供了一个location的参数,我们可以在其中配置query参数,获取这个参数和上面一样,例如:
const User = ({ params: { userID },location: { query } }) => {
)
}
如果想深入了解,大家可以自己尝试一下吧!