视频演示:
https://www.bilibili.com/video/BV1La4y1a7Rp/
工程概述:
- 前后端分离,进行简单增查改删(CRUD)
- 前端使用 React
- 后端使用 Spring Data JPA
- 数据库使用 MySQL
后台端代码上一节已经展示,这里将不再重复,仅展示 React 代码既可。
往期内容
内容
01
Vue+Spring Boot JPA+MySQL 增查改删
02
Thymeleaf+Spring Boot JPA+MySQL 增查改删
03
Vue+Spring Boot 文件操作,上传、预览和删除
04
Thymeleaf+Spring Boot 文件操作,上传、预览和删除
EmployeeService.js
import http from "../http-common";
class EmployeeService {getAll(pageNumber) {return http.get(`/employee?page=${pageNumber}`);
}
get(id) {return http.get(`/employee/${id}`);
}
create(data) {return http.post("/employee", data);
}
update(data) {return http.put("/employee", data);
}
delete(id) {return http.delete(`/employee/${id}`);
}
}
export default new EmployeeService();
EmployeesCreateComponent.js
import React, {Component} from "react";
import {Redirect} from "react-router-dom";
import EmployeeService from "../services/EmployeeService";
export default class EmployeesCreateComponent extends Component {constructor(props) {super(props);
this.saveEmployee = this.saveEmployee.bind(this);
this.onChangeName = this.onChangeName.bind(this);
this.onChangeGender = this.onChangeGender.bind(this);
this.onChangeAge = this.onChangeAge.bind(this);
this.onChangeIntroduce = this.onChangeIntroduce.bind(this);
this.state = {
id: null,
name: "",
gender: "MALE",
age: 18,
introduce: "",
ageRange: [],
redirect: false
};
}
componentDidMount() {
// 初始化年龄下拉列表
var rows = [], i = 17, len = 60;
while (++i <= len) rows.push(i);
this.setState({ageRange : rows})
}
onChangeName(e) {
this.setState({name: e.target.value});
}
onChangeGender(e) {
this.setState({gender: e.target.value});
}
onChangeAge(e){
this.setState({age: e.target.value});
}
onChangeIntroduce(e){
this.setState({introduce: e.target.value});
}
// 保存
saveEmployee() {
var data = {
name: this.state.name,
gender: this.state.gender,
age: this.state.age,
introduce: this.state.introduce
};
EmployeeService.create(data)
.then(response => {
this.setState({redirect: true});
})
.catch(e => {console.log(e);
});
}
render() {const { redirect} = this.state;
return (
<div className="submit-form">
{redirect ? (<Redirect to='/employees'/>) : (
<div>
<div className="form-group">
<label htmlFor="name">Name</label>
<input
type="text"
className="form-control"
id="name"
required
value={this.state.name}
onChange={this.onChangeName}
name="name"
/>
</div>
<div className="form-group">
<input
type="radio"
id="male"
name="gender"
value="MALE"
onChange={this.onChangeGender}
/>
<label htmlFor="male">Male</label>
<input
type="radio"
id="female"
name="gender"
value="FEMALE"
onChange={this.onChangeGender}
/>
<label htmlFor="female">Female</label>
<div className="form-group">
<label> Age:</label>
<select className="form-control" value={this.state.age} name="age" onChange={this.onChangeAge}>
{this.state.ageRange.map((a, index) => (<option value={a} key={index}>{a}</option>
))}
</select>
</div>
<div className="form-group">
<label> Introduce:</label>
<textarea className="form-control" value={this.state.introduce} name="introduce" onChange={this.onChangeIntroduce} ></textarea>
</div>
</div>
<button onClick={this.saveEmployee} className="btn btn-success">
Add Employee
</button>
</div>
)}
</div>
);
}
}
EmployeesEditComponent.js
import React, {Component} from "react";
import EmployeesService from "../services/EmployeeService";
export default class Tutorial extends Component {constructor(props) {super(props);
this.getEmployee = this.getEmployee.bind(this);
this.onChangeName = this.onChangeName.bind(this);
this.onChangeGender = this.onChangeGender.bind(this);
this.onChangeAge = this.onChangeAge.bind(this);
this.onChangeIntroduce = this.onChangeIntroduce.bind(this);
this.updateEmployee = this.updateEmployee.bind(this);
this.state = {
currentEmployee: {
id: null,
name: "",
gender: "MALE",
age: 0,
introduce: ""
},
ageRange: []};
}
componentDidMount() {
// 初始化年龄列表
var rows = [], i = 17, len = 60;
while (++i <= len) rows.push(i);
this.setState({ageRange : rows})
// 根据 ID 获取员工信息
this.getEmployee(this.props.match.params.id);
}
onChangeName(e) {
const name = e.target.value;
this.setState(function(prevState) {
return {
currentEmployee: {
...prevState.currentEmployee,
name: name
}
};
});
}
onChangeGender(e) {
const gender = e.target.value;
this.setState(function(prevState) {
return {
currentEmployee: {
...prevState.currentEmployee,
gender: gender
}
};
});
}
onChangeAge(e) {
const age = e.target.value;
this.setState(function(prevState) {
return {
currentEmployee: {
...prevState.currentEmployee,
age: age
}
};
});
}
onChangeIntroduce(e) {
const introduce = e.target.value;
this.setState(function(prevState) {
return {
currentEmployee: {
...prevState.currentEmployee,
introduce: introduce
}
};
});
}
// 根据 ID 获取员工信息
getEmployee(id) {EmployeesService.get(id)
.then(response => {
this.setState({currentEmployee: response.data.content});
console.log(response.data);
})
.catch(e => {console.log(e);
});
}
// 更新员工信息
updateEmployee() {EmployeesService.update(this.state.currentEmployee)
.then(response => {console.log(response.data);
this.props.history.push('/employees');
})
.catch(e => {console.log(e);
});
}
render() {const { currentEmployee} = this.state;
return (
<div>
<div className="submit-form">
<form>
<div className="form-group">
<label htmlFor="name">Name</label>
<input
type="text"
className="form-control"
id="name"
value={currentEmployee.name}
onChange={this.onChangeName}
/>
</div>
<div className="form-group">
<input
type="radio"
id="male"
name="gender"
checked={currentEmployee.gender === "MALE"}
value="MALE"
onChange={this.onChangeGender}
/>
<label htmlFor="male">Male</label>
<input
type="radio"
id="female"
name="gender"
checked={currentEmployee.gender === "FEMALE"}
value="FEMALE"
onChange={this.onChangeGender}
/>
<label htmlFor="female">Female</label>
<div className="form-group">
<label> Age:</label>
<select className="form-control" value={this.state.currentEmployee.age} name="age" onChange={this.onChangeAge}>
{this.state.ageRange.map((a, index) => (<option value={a} key={index}>{a}</option>
))}
</select>
</div>
<div className="form-group">
<label> Introduce:</label>
<textarea className="form-control" value={this.state.currentEmployee.introduce} name="introduce" onChange={this.onChangeIntroduce} ></textarea>
</div>
</div>
</form>
<button
type="submit"
className="btn btn-success"
onClick={this.updateEmployee}
>
Update Employee
</button>
<p>{this.state.message}</p>
</div>
</div>
);
}
}
EmployeesListComponent.js
import React, {Component} from "react";
import EmployeeService from '../services/EmployeeService';
import Pagination from "react-js-pagination";
import Table from 'react-bootstrap/Table';
import Button from 'react-bootstrap/Button';
export default class EmployeesListComponent extends Component {constructor(props) {super(props);
this.retrieveEmployee = this.retrieveEmployee.bind(this);
this.state = {employees: [], // 数据
activePage: 1, // 默认首页
itemsCountPerPage: 3, // 每页记录数
totalItemsCount: 0, // 总记录数
pageRangeDisplayed: 5 // 分页栏只显示 5 个分页
};
}
// 点击分页
handlePageChange(activePage) {this.setState({activePage: activePage});
this.retrieveEmployee(activePage);
}
componentDidMount() {
// 获取首页
this.retrieveEmployee(1);
}
// 根据 ID 删除员工
deleteEmployee(id){EmployeeService.delete(id).then(response =>{
// 删除成功后, 也可以直接调用后台获取当前页面数据
this.retrieveEmployee(this.state.activePage);
});
}
// 编辑页面
editEmployee(id) {this.props.history.push('/employee/'+id)
}
// 获取数据方法
retrieveEmployee(activePage) {
// 前端页面从 1 开始,而后台页面从 0 开始,所以 -1
EmployeeService.getAll(activePage-1)
.then(response => {
this.setState({
employees: response.data.content.content,
totalItemsCount: response.data.content.totalElements,
itemsCountPerPage: response.data.content.size
});
console.log(response.data);
})
.catch(e => {console.log(e);
});
}
render() {const { employees} = this.state;
return (
<div>
<Table striped bordered hover>
<thead >
<tr>
<th >ID</th>
<th >Name</th>
<th >Gender</th>
<th >Age</th>
<th >Introduce</th>
<th >Actions</th>
</tr>
</thead>
<tbody>
{employees && employees.map((tutorial, index) => (<tr key={index}>
<td>{tutorial.id}</td>
<td>{tutorial.name}</td>
<td>{tutorial.gender}</td>
<td>{tutorial.age}</td>
<td>{tutorial.introduce}</td>
<td>
<Button variant="info" onClick={() => this.editEmployee(tutorial.id) }> 编辑 </Button>
<Button variant="danger" onClick={() => this.deleteEmployee(tutorial.id) }> 删除 </Button>
</td>
</tr>
))}
</tbody>
</Table>
{ this.state.totalItemsCount > 0 &&
<div className="col-md-6">
<Pagination
activePage={this.state.activePage}
itemsCountPerPage={this.state.itemsCountPerPage}
totalItemsCount={this.state.totalItemsCount}
pageRangeDisplayed={this.state.pageRangeDisplayed}
onChange={this.handlePageChange.bind(this)}
itemClass="page-item"
linkClass="page-link"
/>
</div>
}
</div>
);
}
}