Appearance
嵌套路由
本节目标:理解“嵌套路由”的核心思路,并能把它用于实际开发或面试表达。
src\utils.js
export const UserAPI = {
list() {
let usersStr = localStorage.getItem('users');
let users = usersStr ? JSON.parse(usersStr) : [];
return users;
},
add(user) {
let users = UserAPI.list();
users.push(user);
localStorage.setItem('users', JSON.stringify(users));
},
find(id) {
let users = UserAPI.list();
return users.find(user => user.id === id)
}
}
//[{id:1,name:'zhangsan'}]src\components\User.js
import React from "react";
import UserList from './UserList';
import UserAdd from './UserAdd';
import UserDetail from './UserDetail';
import { Route, Link } from "../react-router-dom";
export default class User extends React.Component {
render() {
console.log(this.props.location.state);
return (
<div>
<ul>
<li><Link to="/user/list" >用户列表</Link></li>
<li><Link to="/user/add">添加用户</Link></li>
</ul>
<Route path="/user/list" component={UserList} />
<Route path="/user/add" component={UserAdd} />
<Route path="/user/detail/:id" component={UserDetail} />
</div>
)
}
}src\components\UserAdd.jsimport React, { Component } from 'react'
import { UserAPI } from '../utils';
import { Prompt } from '../react-router-dom';
export default class UserAdd extends Component {
state = { isBlocking: false } //是否阻止跳转,默认值是不阻止
nameRef = React.createRef()
handleSubmit = (event) => {
event.preventDefault();
this.setState({ isBlocking: false }, () => {
let name = this.nameRef.current.value;
UserAPI.add({ id: Date.now() + "", name });
this.props.history.push('/user/list');
});
}
handleChange = (event) => {
this.setState({ isBlocking: event.target.value.length > 0 });
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<Prompt
when={this.state.isBlocking}
message={(location) => `请问你是确定要离开当前页面,跳转到${location.pathname}吗?`}
/>
<input type="text" ref={this.nameRef} onChange={this.handleChange} />
<button type="submit">添加</button>
</form>
)
}
}src\components\UserList.js
import React, { Component } from 'react'
import { UserAPI } from '../utils';
import { Link } from '../react-router-dom';
export default class UserList extends Component {
state = { users: [] }
componentDidMount() {
let users = UserAPI.list();
this.setState({ users });
}
render() {
return (
<ul>
{
this.state.users.map((user) => (
<li key={user.id}>
<Link to={{
pathname: `/user/detail/${user.id}`,
state: user
}}>
{user.name}
</Link>
</li>
))
}
</ul>
)
}
}src\components\UserDetail.js
import React, { Component } from 'react'
import { UserAPI } from '../utils';
export default class UserDetail extends Component {
state = { user: {} }
componentDidMount() {
let user = this.props.location.state;
if (!user) {//如果不是从列表页跳转的,而是直接刷新的话,user就是undefined
let id = this.props.match.params.id;
user = UserAPI.find(id);
}
if (user) this.setState({ user });
}
render() {
let user = this.state.user;
return (
<div>
<p>id:{user.id}</p>
<p>name:{user.name}</p>
</div>
)
}
}