生成项目
create-react-app react-router-4-lesson
cd react-router-4-lesson
yarn start
安装react-router-dom
npm install react-router-dom -S
配置基本路由
src/App.js
import React from 'react'
import {
BrowserRouter as Router,
Route,
Link
} from 'react-router-dom'
const Home = () => (
<div>
<h2>首页</h2>
</div>
)
const User = () => (
<div>
<h2>用户管理</h2>
</div>
)
const Profile = () => (
<div>
<h3>个人设置</h3>
</div>
)
const App = () => (
<Router>
<div>
<ul>
<li><Link to="/">主页</Link></li>
<li><Link to="/user">用户管理</Link></li>
<li><Link to="/profile">个人设置</Link></li>
</ul>
<hr/>
<Route exact path="/" component={Home}/>
<Route path="/user" component={User}/>
<Route path="/profile" component={Profile}/>
</div>
</Router>
)
export default App
npm install bootstrap -S
import 'bootstrap/dist/css/bootstrap.css';
src/App.js
<div className="navbar navbar-default"> <div className="container-fluid">
<div className="navbar-header">
<div className="navbar-brand">
<Link to="/">学生管理系统</Link>
</div>
</div>
<div>
<ul className="nav navbar-nav">
<li><Link to="/">首页</Link></li>
<li><Link to="/user">用户管理</Link></li>
<li><Link to="/profile">个人设置</Link></li>
</ul>
</div>
</div>
</div>
<div className="container">
<Route exact path="/" component={Home}/>
<Route path="/user" component={User}/>
<Route path="/profile" component={Profile}/>
</div>
先把Home、User、Profile都独立到各自不同的组件文件中去
实现用户管理中的二级路由
src/User.js
import React from 'react';
import {Route,Link} from 'react-router-dom';
import UserList from './UserList';
import UserAdd from './UserAdd';
const User = () => (
<div className="row">
<div className="col-md-2">
<ul className="nav nav-pills nav-stacked">
<li role="presentation"><Link to="/user/list">用户列表</Link></li>
<li role="presentation"><Link to="/user/add">增加用户</Link></li>
</ul>
</div>
<div className="col-md-10">
<Route path={`/user/list`} component={UserList}/>
<Route path={`/user/add`} component={UserAdd}/>
</div>
</div>
)
export default User
src/User.js
import React from 'react';
import {Route,Link} from 'react-router-dom';
import UserList from './UserList';
import UserAdd from './UserAdd';
import UserDetail from './UserDetail';
const User = () => (
<div className="row">
<div className="col-md-2">
<div className="col-md-10">
<Route path={`/user/list`} component={UserList}/>
<Route path={`/user/add`} component={UserAdd}/>
<Route path={`/user/detail/:id`} component={UserDetail}/>
</div>
</div>
)
src/UserDetail.js
import React from 'react'
export default class UserDetail extends React.Component{
render(){
let {match} = this.props;
return (
<div className="panel panel-default">
<div className="panel-body">
ID:{match.params.id}
姓名:
</div>
</div>
)
}
}
UserList.js
import React from 'react';
import {Link} from 'react-router-dom';
const UserList = () => (
<ul className="list-group">
<li className="list-group-item">
<Link to="/user/detail/1">张三</Link>
</li>
<li className="list-group-item">
<Link to="/user/detail/2">李四</Link>
</li>
</ul>
)
export default UserList
src/App.js
import {Switch} from 'react-router-dom'
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/user" component={User}/>
<Route path="/profile" component={Profile}/>
</Switch>
src/App.js
<Router>
<div>
<div className="navbar navbar-inverse">
<div className="container-fluid">
<div className="navbar-header">
<div className="navbar-brand">
<Link to="/">学生管理系统</Link>
</div>
</div>
<div>
<ul className="nav navbar-nav">
<li><Link to="/zhufengpeixun">品牌</Link></li>
</ul>
</div>
</div>
</div>
<div className="container">
<Switch>
<Route path="/:name" render={({match})=>(<div>{match.params.name}</div>)}/>
</Switch>
</div>
</div>
</Router>
src/App.js
import React from 'react'
import 'bootstrap/dist/css/bootstrap.css';
import {
BrowserRouter as Router,
Route,
Link,
Switch
} from 'react-router-dom'
import Home from './Home';
import User from './User';
import Profile from './Profile';
import PrivateRoute from './PrivateRoute';
import Login from './Login';
const App = () => (
<Router>
<div>
<div className="navbar navbar-inverse">
<div className="container-fluid">
<div className="navbar-header">
<div className="navbar-brand">
<Link to="/">学生管理系统</Link>
</div>
</div>
<div>
<ul className="nav navbar-nav">
<li><Link to="/">首页</Link></li>
<li><Link to="/user">用户管理</Link></li>
<li><Link to="/profile">个人设置</Link></li>
<li><Link to="/zhufengpeixun">品牌</Link></li>
</ul>
<ul className="nav navbar-nav navbar-right">
<li><Route path="/" render={({history}) => (<a onClick={() => {localStorage.clear();history.push('/');}}>退出</a>)}/></li>
</ul>
</div>
</div>
</div>
<div className="container">
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/user" component={User}/>
<PrivateRoute path="/profile" component={Profile}/>
<Route path="/login" component={Login}/>
<Route path="/:name" render={({match}) => (<div>{match.params.name}</div>)}/>
</Switch>
</div>
</div>
</Router>
)
export default App
src/PrivateRoute.js
import React from 'react'
import {Route,Redirect} from 'react-router-dom'
const PrivateRoute = ({component: Component,...rest}) => (
<Route {...rest} render={props => (
localStorage.getItem('login') ? <Component/> : <Redirect to={{
pathname: '/login',
state: {from: props.location}
}}/>
)}>
</Route>
)export default PrivateRoute
src/Login.js
import React from 'react';
import {withRouter} from 'react-router-dom';
class Login extends React.Component{
render(){
let {history,location} = this.props;
return (
<div>
<button className="btn btn-primary" onClick={()=>{
localStorage.setItem('login','true');
history.push(location.state.from.pathname);
}}>登录</button>
</div>
)
}
}
export default withRouter(Login)
src/MenuLink.js
import React from 'react'
import {Route, Link} from 'react-router-dom'
const MenuLink = ({ label, to, activeOnlyWhenExact }) => (
<Route path={to} exact={activeOnlyWhenExact} children={({ match }) => (
<li className={match ? 'active' : ''}>
<Link to={to}>{label}</Link>
</li>
)}/>
)
export default MenuLink
src/App.js
<MenuLink activeOnlyWhenExact={true} to="/" label="首页"/>
<MenuLink activeOnlyWhenExact={true} to="/user" label="用户管理"/>
<MenuLink activeOnlyWhenExact={true} to="/profile" label="个人设置"/>
src/UserAdd.js
import React from 'react';
import {Prompt} from 'react-router-dom';
export default class UserAdd extends React.Component {
constructor(props) {
super(props);
this.state = {blocking: false};
}
handleChange = (event) => {
this.setState({
blocking: event.target.value && event.target.value.length > 0
});
}
handleSubmit = (event) => {
event.preventDefault();
this.setState({
blocking: false
}, () => {
this.props.history.push('/user/list');
});
}
render() {
return (
<div>
<Prompt
when={this.state.blocking}
message={location => (
`你确定你要去 ${location.pathname} 吗?`
)}
/>
<form onSubmit={this.handleSubmit}>
<div className="form-group">
<label htmlFor="name">姓名</label>
<input ref={(ref) => this.name = ref} type="text" onChange={this.handleChange}
className="form-control"/>
</div>
<div className="form-group">
<button type="submit" className="btn btn-primary">提交</button>
</div>
</form>
</div>
)
}
}
src/App.js
<Route component={NoMatch}/>
src/NoMatch.js
import React from 'react'
const NoMatch = () => (
<div>
<h3>此路径不存在</h3>
</div>
)
export default NoMatch