React+Spring Data JPA+MySQL 增查改刪

視頻演示:

https://www.bilibili.com/video/BV1La4y1a7Rp/

工程概述:

  1. 前後端分離,進行簡單增查改刪(CRUD)

  2. 前端使用React

  3. 後端使用Spring Data JPA

  4. 數據庫使用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>

    );
   
  }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章