В пост- рендеринге сервиса RESTful с React мы создали простой пользовательский интерфейс, который отображает список сотрудников, извлеченный из сервиса RESTful. В рамках этого поста мы расширим то же приложение для поддержки операций добавления и удаления сотрудников.
Мы начнем с обновления бэкэнд — интерфейса реагирующего приложения с операцией добавления / удаления сотрудников, а также с изменения существующего метода get employee для возврата списка сотрудников, выполнив следующие действия:
Шаг 1. Определите метод addEmployee, помеченный @PostMapping («/ employee / add»), который будет добавлять сотрудника в список сотрудников на уровне класса:
1
2
3
4
5
6
7
|
@PostMapping ( "/employee/add" ) public List<Employee> addEmployee( final @RequestBody Employee employee) { System.out.println( "Adding employee with name : " + employee.getName()); if (employee.getName() != null && employee.getName().length() > 0 ) employeeList.add( new Employee(employeeList.size(), employee.getName(), "IT" )); return employeeList; } |
Шаг 2. Определите метод deleteEmployee, помеченный @PostMapping («/ employee / delete»), который будет удалять сотрудника из списка сотрудников уровня класса, соответствующего имени сотрудника, следующим образом:
1
2
3
4
5
6
7
8
9
|
@PostMapping ( "/employee/delete" ) public List<Employee> deleteEmployee( final @RequestBody Employee employee) { System.out.println( "Deleting employee with name : " + employee.getName()); final Optional<Employee> optional = employeeList.stream().filter(e -> e.getName().equalsIgnoreCase(employee.getName())).findAny(); if (optional.isPresent()){ employeeList.remove(optional.get()); } return employeeList; } |
В конечном итоге ReactAppApplication.java должен выглядеть следующим образом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@SpringBootApplication @RestController public class ReactAppApplication { final List<Employee> employeeList = new ArrayList<>(); public static void main(String[] args) { SpringApplication.run(ReactAppApplication. class , args); } @GetMapping ( "/employee/get" ) public List<Employee> get() { return employeeList; } @PostMapping ( "/employee/add" ) public List<Employee> add( final @RequestBody Employee employee) { System.out.println( "Adding employee with name : " + employee.getName()); if (employee.getName() != null && employee.getName().length() > 0 ) employeeList.add( new Employee(employeeList.size(), employee.getName(), "IT" )); return employeeList; } @PostMapping ( "/employee/delete" ) public List<Employee> delete( final @RequestBody Employee employee) { System.out.println( "Deleting employee with name : " + employee.getName()); final Optional<Employee> optional = employeeList.stream().filter(e -> e.getName().equalsIgnoreCase(employee.getName())).findAny(); if (optional.isPresent()){ employeeList.remove(optional.get()); } return employeeList; } } |
Шаг 3: Определите метод / обработчик addEmployee в компоненте ReactApp, который выполняет вызов POST с именем сотрудника в качестве полезной нагрузки для метода addEmployee, который мы только что определили в нашем контроллере, следующим образом:
/Users/ArpitAggarwal/react-app/app/components/react-app.jsx
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
addEmployee(employeeName){ let _this = this ; this .Axios.post( '/add' , { name: employeeName }) .then(function (response) { console.log(response); _this.setState({employees: response.data}); }) . catch (function (error) { console.log(error); }); } |
Шаг 4: Привязать обработчик addEmployee в конструкторе компонента ReactApp :
1
2
3
4
5
6
7
8
9
|
constructor(props) { super (props); this .state = {employees: []}; this .addEmployee = this .addEmployee.bind( this ); this .Axios = axios.create({ baseURL: "/employee" , headers: { 'content-type' : 'application/json' , 'creds' : 'user' } }); } |
Шаг 5. Рендеринг дочернего компонента — AddEmployee как часть метода рендеринга компонента ReactApp , передавая обработчик addEmployee в качестве реагирующих действий для установления родительского дочернего взаимодействия:
1
2
3
4
5
6
7
8
|
render() { return ( <div> <AddEmployee addEmployee={ this .addEmployee}/> <EmployeeList employees={ this .state.employees}/> </div> ) } |
Шаг 6: Создайте компонент add-employee внутри каталога компонентов следующим образом:
1
2
|
cd react-app /app/components/ touch add-employee.jsx |
И скопируйте следующий контент:
реагировать-приложение / приложения / компоненты / дополнения employee.jsx
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import React, { Component, PropTypes } from 'react' export default class AddEmployee extends React.Component { render(){ return ( <div> <input type = 'text' ref = 'input' /> <button onClick = {(e) => this .handleClick(e)}> Add Employee </button> </div> ) } handleClick(e) { const node = this .refs.input const text = node.value.trim() console.log(text); this .props.addEmployee(text) node.value = '' } } |
Определенная выше функция handleClick (e) вызывается при нажатии кнопки «Добавить сотрудника», которая дополнительно вызывает обработчик addEmployee, определенный в ReactApp, с использованием реквизита .
Имея все это в наличии, наше реагирующее приложение может выполнять операции добавления сотрудников. Далее мы расширим то же самое для поддержки операции удаления сотрудника, выполнив следующие шаги
Шаг 7: Определите обработчик deleteEmployee и привяжите его в ReactApp так же, как мы делали для обработчика addEmployee :
/Users/ArpitAggarwal/react-app/app/components/react-app.jsx
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
constructor(props) { super (props); this .state = {employees: []}; this .addEmployee = this .addEmployee.bind( this ); this .deleteEmployee = this .deleteEmployee.bind( this ); this .Axios = axios.create({ baseURL: "/employee" , headers: { 'content-type' : 'application/json' , 'creds' : 'user' } }); } deleteEmployee(employeeName){ let _this = this ; this .Axios.post( '/delete' , { name: employeeName }) .then(function (response) { _this.setState({employees: response.data}); console.log(response); }) . catch (function (error) { console.log(error); }); } |
Шаг 8: Передайте обработчик deleteEmployee компоненту EmployeeList, который затем передаст его дочернему контейнеру:
1
2
3
4
5
6
7
8
|
render() { return ( <div> <AddEmployee addEmployee={ this .addEmployee}/> <EmployeeList employees={ this .state.employees} deleteEmployee={ this .deleteEmployee}/> </div> ) } |
В конце концов, компонент ReactApp должен выглядеть следующим образом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
'use strict' ; const React = require( 'react' ); var axios = require( 'axios' ); import EmployeeList from './employee-list.jsx' import AddEmployee from './add-employee.jsx' export default class ReactApp extends React.Component { constructor(props) { super (props); this .state = {employees: []}; this .addEmployee = this .addEmployee.bind( this ); this .deleteEmployee = this .deleteEmployee.bind( this ); this .Axios = axios.create({ baseURL: "/employee" , headers: { 'content-type' : 'application/json' , 'creds' : 'user' } }); } componentDidMount() { let _this = this ; this .Axios.get( '/get' ) .then(function (response) { console.log(response); _this.setState({employees: response.data}); }) . catch (function (error) { console.log(error); }); } addEmployee(employeeName){ let _this = this ; this .Axios.post( '/add' , { name: employeeName }) .then(function (response) { console.log(response); _this.setState({employees: response.data}); }) . catch (function (error) { console.log(error); }); } deleteEmployee(employeeName){ let _this = this ; this .Axios.post( '/delete' , { name: employeeName }) .then(function (response) { _this.setState({employees: response.data}); console.log(response); }) . catch (function (error) { console.log(error); }); } render() { return ( <div> <AddEmployee addEmployee={ this .addEmployee}/> <EmployeeList employees={ this .state.employees} deleteEmployee={ this .deleteEmployee}/> </div> ) } } |
Шаг 9: Обновите компонент EmployeeList, чтобы передать обработчик deleteEmployee своему дочернему компоненту — Employee , импортировав его вместе с изменением в методе render, чтобы получить столбец Delete:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
const React = require( 'react' ); import Employee from './employee.jsx' export default class EmployeeList extends React.Component{ render() { var employees = this .props.employees.map((employee, i) => <Employee key={i} employee={employee} deleteEmployee={() => this .props.deleteEmployee(employee.name)}/> ); return ( <table> <tbody> <tr> <th>ID</th> <th>Name</th> <th>Department</th> <th>Delete</th> </tr> {employees} </tbody> </table> ) } } |
Шаг 10: Обновите компонент Employee для рендеринга — компонент DeleteEmployee, передавший обработчик deleteEmployee :
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
const React = require( 'react' ); import DeleteEmployee from './delete-employee.jsx' export default class Employee extends React.Component{ render() { return ( <tr> <td>{ this .props.employee.id}</td> <td>{ this .props.employee.name}</td> <td>{ this .props.employee.department}</td> <td><DeleteEmployee deleteEmployee={ this .props.deleteEmployee}/></td> </tr> ) } } |
Шаг 11: Создайте компонент delete-employee внутри каталога компонентов:
1
2
|
cd react-app/app/components/ touch delete-employee.jsx |
И скопируйте следующий контент:
реагировать-приложение / приложения / компоненты / удаление-employee.jsx
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
import React, { Component, PropTypes } from 'react' export default class DeleteEmployee extends React.Component { render(){ return ( <button onClick = {(employeeName) => this.handleDelete(employeeName)}> Delete < /button > ) } handleDelete(employeeName) { this.props.deleteEmployee(employeeName); } } |
Определенная выше функция handleDelete (employeeName) вызывается при нажатии кнопки «Удалить», что дополнительно вызывает обработчик deleteEmployee, определенный в ReactApp, с использованием реквизита .
Со всеми на месте структура каталогов должна выглядеть так:
Теперь перезапустите приложение и посетите http: // localhost: 8080 , оно должно выглядеть так, как показано на скриншоте ниже, как только вы добавите несколько сотрудников.
Полный исходный код размещен на github .
Ссылка: | Обработка событий в действии от нашего партнера JCG |