{"id":8333,"date":"2021-02-10T17:11:05","date_gmt":"2021-02-10T11:41:05","guid":{"rendered":"https:\/\/www.h2kinfosys.com\/blog\/?p=8333"},"modified":"2021-02-10T17:11:07","modified_gmt":"2021-02-10T11:41:07","slug":"react-with-java-services-using-rest-service","status":"publish","type":"post","link":"https:\/\/www.h2kinfosys.com\/blog\/react-with-java-services-using-rest-service\/","title":{"rendered":"React with Java Services using REST Service"},"content":{"rendered":"\n<p>React.js is a lightweight JavaScript framework, which is oriented toward the creation of <a href=\"https:\/\/medium.com\/@smarth55\/web-component-based-architecture-8837052b9e50\" class=\"rank-math-link\" rel=\"nofollow noopener\" target=\"_blank\">component-based web <\/a>UIs. React does not provide any means for communicating with the backend, but we can use any communication library from inside React components.<\/p>\n\n\n\n<p>Here we are developing a simple React application consuming the REST API.&nbsp;<\/p>\n\n\n\n<p><strong>Step 1:<\/strong> React.js Development Environment Set Up<\/p>\n\n\n\n<p>There are number of ways to use React.js. The simplest way is to include React libraries in the &lt;script> tags on the page.\u00a0<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">&lt;!DOCTYPE html>\n&lt;html lang=\"en\" dir=\"ltr\">\n\u00a0\u00a0&lt;head>\n\u00a0\u00a0\u00a0\u00a0&lt;meta charset=\"utf-8\">\n\u00a0\u00a0\u00a0\u00a0&lt;title>&lt;\/title>\n\u00a0\u00a0&lt;\/head>\n\u00a0\u00a0&lt;body>\n\u00a0\u00a0\u00a0\u00a0&lt;div id=\"hello_container\" class=\"\">&lt;\/div>\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/unpkg.com\/react@16\/umd\/react.development.js\" crossorigin>&lt;\/script>\n\u00a0\u00a0\u00a0\u00a0&lt;script src=\"https:\/\/unpkg.com\/react-dom@16\/umd\/react-dom.development.js\" crossorigin>&lt;\/script>\n\u00a0\u00a0\u00a0\u00a0&lt;script>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0class Hello extends React.Component {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0constructor(props) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0super(props);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0render() {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return React.createElement(\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'div',\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0null,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0`Hello ${this.props.name}!`\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ReactDOM.render(React.createElement(Hello, {name: 'React'}, null), document.querySelector('#hello_container'));\n\u00a0\u00a0\u00a0\u00a0&lt;\/script>\n\u00a0\u00a0&lt;\/body>\n&lt;\/html>\n<\/pre>\n\n\n\n<p><strong>Step 2:<\/strong> Backend Communication Service Implementation<\/p>\n\n\n\n<p>It is a great idea to put all the related functionalities in one place. Putting our functionality behind a service that exposes certain APIs ensures more flexibility and testability for our application. Therefore, we can create a communication service class, which implements all the <a href=\"https:\/\/www.h2kinfosys.com\/blog\/crud-operations-db\/\" class=\"rank-math-link\">basic CRUD operations<\/a> for exchanging data with the server and exposes these operations as a method for all React components. To make your UI more responsive, you need to implement the methods as asynchronous.<\/p>\n\n\n\n<p><strong>src\/shared\/mock-item-service,js \u2013 mock ItemService:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">class ItemService {\n\u00a0\u00a0constructor() {\n\u00a0\u00a0\u00a0\u00a0this.items = [\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{link:1, name:\"test1\", summary:\"Summary Test 1\", year:\"2001\", country:\"us\", price:\"1000\", description:\"Desc 1\"},\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{link:2, name:\"test2\", summary:\"Summary Test 2\", year:\"2002\", country:\"uk\", price:\"2000\", description:\"Desc 2\"},\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{link:3, name:\"test3\", summary:\"Summary Test 3\", year:\"2003\", country:\"cz\", price:\"3000\", description:\"Desc 3\"},\n\u00a0\u00a0\u00a0\u00a0];\n\u00a0\u00a0}\n\u00a0\u00a0async retrieveItems() {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return Promise.resolve(this.items);\n\u00a0\u00a0}\n\u00a0\u00a0async getItem(itemLink) {\n\u00a0\u00a0\u00a0\u00a0for(var i = 0; i &lt; this.items.length; i++) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if ( this.items[i].link === itemLink) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return Promise.resolve(this.items[i]);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0return null;\n\u00a0\u00a0}\n\u00a0\u00a0async createItem(item) {\n\u00a0\u00a0\u00a0\u00a0console.log(\"ItemService.createItem():\");\n\u00a0\u00a0\u00a0\u00a0console.log(item);\n\u00a0\u00a0\u00a0\u00a0return Promise.resolve(item);\n\u00a0\u00a0}\n\u00a0\u00a0async deleteItem(itemId) {\n\u00a0\u00a0\u00a0\u00a0console.log(\"ItemService.deleteItem():\");\n\u00a0\u00a0\u00a0\u00a0console.log(\"item ID:\" + itemId);\n\u00a0\u00a0}\n\u00a0\u00a0async updateItem(item) {\n\u00a0\u00a0\u00a0\u00a0console.log(\"ItemService.updateItem():\");\n\u00a0\u00a0\u00a0\u00a0console.log(item);\n\u00a0\u00a0}\n}\nexport default ItemService;\n<\/pre>\n\n\n\n<p><strong>Step 3:<\/strong> CRUD UI Implementation<\/p>\n\n\n\n<p>React supports component hierarchies, where each component have a state and that state can be shared between related components. Also, behavior of each component&#8217;s can be customized by passing properties to it. Therefore, we can develop the main component that contains the list of collection items and works as a placeholder for displaying the forms for corresponding CRUD actions. Using the stuff that is generated by the create-react-app tool, we can change the content of app.js as follows.<\/p>\n\n\n\n<p><strong>src\/App.js \u2013 the main component used as the application frame:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import React, { Component } from 'react';\nimport '.\/App.css';\nimport ItemDetails from '.\/item-details';\nimport NewItem from '.\/new-item';\nimport EditItem from '.\/edit-item';\nimport ItemService from '.\/shared\/mock-item-service';\nclass App extends Component {\n\u00a0\u00a0constructor(props) {\n\u00a0\u00a0\u00a0\u00a0super(props);\n\u00a0\u00a0\u00a0\u00a0this.itemService = new ItemService();\n\u00a0\u00a0\u00a0\u00a0this.onSelect = this.onSelect.bind(this);\n\u00a0\u00a0\u00a0\u00a0this.onNewItem = this.onNewItem.bind(this);\n\u00a0\u00a0\u00a0\u00a0this.onEditItem = this.onEditItem.bind(this);\n\u00a0\u00a0\u00a0\u00a0this.onCancel = this.onCancel.bind(this);\n\u00a0\u00a0\u00a0\u00a0this.onCancelEdit = this.onCancelEdit.bind(this);\n\u00a0\u00a0\u00a0\u00a0this.onCreateItem = this.onCreateItem.bind(this);\n\u00a0\u00a0\u00a0\u00a0this.onUpdateItem = this.onUpdateItem.bind(this);\n\u00a0\u00a0\u00a0\u00a0this.onDeleteItem = this.onDeleteItem.bind(this);\n\u00a0\u00a0\u00a0\u00a0this.state = {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0showDetails: false,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0editItem: false,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0selectedItem: null,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0newItem: null\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0}\n\u00a0\u00a0componentDidMount() {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.getItems();\n\u00a0\u00a0}\n\u00a0\u00a0render() {\n\u00a0\u00a0\u00a0\u00a0const items = this.state.items;\n\u00a0\u00a0\u00a0\u00a0if(!items) return null;\n\u00a0\u00a0\u00a0\u00a0const showDetails = this.state.showDetails;\n\u00a0\u00a0\u00a0\u00a0const selectedItem = this.state.selectedItem;\n\u00a0\u00a0\u00a0\u00a0const newItem = this.state.newItem;\n\u00a0\u00a0\u00a0\u00a0const editItem = this.state.editItem;\n\u00a0\u00a0\u00a0\u00a0const listItems = items.map((item) =>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;li key={item.link} onClick={() => this.onSelect(item.link)}>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;span className=\"item-name\">{item.name}&lt;\/span> |\u00a0 {item.summary}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/li>\n\u00a0\u00a0\u00a0\u00a0);\n\u00a0\u00a0\u00a0\u00a0return (\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"App\">\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;ul className=\"items\">\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{listItems}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/ul>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;br\/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;button type=\"button\" name=\"button\" onClick={() => this.onNewItem()}>New Item&lt;\/button>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;br\/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{newItem &amp;&amp; &lt;NewItem onSubmit={this.onCreateItem} onCancel={this.onCancel}\/>}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{showDetails &amp;&amp; selectedItem &amp;&amp; &lt;ItemDetails item={selectedItem} onEdit={this.onEditItem}\u00a0 onDelete={this.onDeleteItem} \/>}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{editItem &amp;&amp; selectedItem &amp;&amp; &lt;EditItem onSubmit={this.onUpdateItem} onCancel={this.onCancelEdit} item={selectedItem} \/>}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div>\n\u00a0\u00a0\u00a0\u00a0);\n\u00a0\u00a0}\n\u00a0\u00a0getItems() {\n\u00a0\u00a0\u00a0\u00a0this.itemService.retrieveItems().then(items => {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.setState({items: items});\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0);\n\u00a0\u00a0}\n\u00a0\u00a0onSelect(itemLink) {\n\u00a0\u00a0\u00a0\u00a0this.clearState();\n\u00a0\u00a0\u00a0\u00a0this.itemService.getItem(itemLink).then(item => {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.setState({\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0showDetails: true,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0selectedItem: item\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0);\n\u00a0\u00a0}\n\u00a0\u00a0onCancel() {\n\u00a0\u00a0\u00a0\u00a0this.clearState();\n\u00a0\u00a0}\n\u00a0\u00a0onNewItem() {\n\u00a0\u00a0\u00a0\u00a0this.clearState();\n\u00a0\u00a0\u00a0\u00a0this.setState({\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0newItem: true\n\u00a0\u00a0\u00a0\u00a0});\n\u00a0\u00a0}\n\u00a0\u00a0onEditItem() {\n\u00a0\u00a0\u00a0\u00a0this.setState({\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0showDetails: false,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0editItem: true,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0newItem: null\n\u00a0\u00a0\u00a0\u00a0});\n\u00a0\u00a0}\n\u00a0\u00a0onCancelEdit() {\n\u00a0\u00a0\u00a0\u00a0this.setState({\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0showDetails: true,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0editItem: false,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0newItem: null\n\u00a0\u00a0\u00a0\u00a0});\n\u00a0\u00a0}\n\u00a0\u00a0onUpdateItem(item) {\n\u00a0\u00a0\u00a0\u00a0this.clearState();\n\u00a0\u00a0\u00a0\u00a0this.itemService.updateItem(item).then(item => {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.getItems();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0);\n\u00a0\u00a0}\n\u00a0\u00a0onCreateItem(newItem) {\n\u00a0\u00a0\u00a0\u00a0this.clearState();\n\u00a0\u00a0\u00a0\u00a0this.itemService.createItem(newItem).then(item => {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.getItems();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0);\n\u00a0\u00a0}\n\u00a0\u00a0onDeleteItem(itemLink) {\n\u00a0\u00a0\u00a0\u00a0this.clearState();\n\u00a0\u00a0\u00a0\u00a0this.itemService.deleteItem(itemLink).then(res => {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.getItems();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0);\n\u00a0\u00a0}\n\u00a0\u00a0clearState() {\n\u00a0\u00a0\u00a0\u00a0this.setState({\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0showDetails: false,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0selectedItem: null,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0editItem: false,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0newItem: null\n\u00a0\u00a0\u00a0\u00a0});\n\u00a0\u00a0}\n}\nexport default App;\nThen we create nested components for basic operations with collection items.\n<strong>src\/new-item.js \u2013 created for new collection items:<\/strong>\nimport React, { Component } from 'react';\nimport '.\/App.css';\nimport Validator from '.\/shared\/validator';\nclass NewItem extends Component {\n\u00a0\u00a0constructor(props) {\n\u00a0\u00a0\u00a0\u00a0super(props);\n\u00a0\u00a0\u00a0\u00a0this.validator = new Validator();\n\u00a0\u00a0\u00a0\u00a0this.onCancel = this.onCancel.bind(this);\n\u00a0\u00a0\u00a0\u00a0this.onSubmit = this.onSubmit.bind(this);\n\u00a0\u00a0\u00a0\u00a0this.handleInputChange = this.handleInputChange.bind(this);\n\u00a0\u00a0\u00a0\u00a0this.state = {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name: '',\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0summary: '',\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0year: '',\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0country: '',\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0description: ''\n\u00a0\u00a0\u00a0\u00a0};\n\u00a0\u00a0}\n\u00a0\u00a0handleInputChange(event) {\n\u00a0\u00a0\u00a0\u00a0const target = event.target;\n\u00a0\u00a0\u00a0\u00a0const value = target.value;\n\u00a0\u00a0\u00a0\u00a0const name = target.name;\n\u00a0\u00a0\u00a0\u00a0this.setState({\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0[name]: value\n\u00a0\u00a0\u00a0\u00a0});\n\u00a0\u00a0}\n\u00a0\u00a0onCancel() {\n\u00a0\u00a0\u00a0\u00a0this.props.onCancel();\n\u00a0\u00a0}\n\u00a0\u00a0onSubmit() {\n\u00a0\u00a0\u00a0\u00a0if(this.validator.validateInputs(this.state)) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.props.onSubmit(this.state);\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0}\n\u00a0\u00a0render() {\n\u00a0\u00a0\u00a0\u00a0return (\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"input-panel\">\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;span className=\"form-caption\">New item:&lt;\/span>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;label className=\"field-name\">Name:&lt;br\/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input value={this.state.name} name=\"name\" maxLength=\"40\" required onChange={this.handleInputChange} placeholder=\"item name\" \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/label>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;label className=\"field-name\">Summary:&lt;br\/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input value={this.state.summary} name=\"summary\" maxLength=\"40\" required onChange={this.handleInputChange} placeholder=\"summary\" \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/label>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;label className=\"field-name\">Year:&lt;br\/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input value={this.state.year} name=\"year\" maxLength=\"4\" pattern=\"[0-9]{1,4}\" onChange={this.handleInputChange} placeholder=\"year\" \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/label>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;label className=\"field-name\">Country:&lt;br\/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input value={this.state.country} name=\"country\" maxLength=\"2\" pattern=\"[a-z|A-Z]{2}\" onChange={this.handleInputChange} placeholder=\"country code\" \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/label>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;label className=\"field-name\">Description:&lt;br\/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;textarea value={this.state.description} name=\"description\" onChange={this.handleInputChange} placeholder=\"description\" \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/label>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;br\/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;button onClick={() => this.onCancel()}>Cancel&lt;\/button>\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;button onClick={() => this.onSubmit()}>Create&lt;\/button>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div>\n\u00a0\u00a0\u00a0\u00a0);\n\u00a0\u00a0}\n}\nexport default NewItem;\n<\/pre>\n\n\n\n<p>Here, we will use the validator class that provides a simple validation for newly created or edited collection items and this class can be shared between components, i.e. it can be used in NewItem and EditItem components in this case.<\/p>\n\n\n\n<p><strong>src\/shared\/validatior.js \u2013 simple validation method for the item form:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">class Validator {\n\u00a0\u00a0validateInputs(inputData) {\n\u00a0\u00a0\u00a0\u00a0let errorMsg = \"\";\n\u00a0\u00a0\u00a0\u00a0if(!inputData.name) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0errorMsg +=\"Please enter name of this item.\\n\"\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0if(!inputData.summary) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0errorMsg +=\"Please enter summary of this item.\\n\"\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0if(inputData.year.toString().match(\/[^0-9]\/g)) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0errorMsg +=\"Year must be a number.\\n\"\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0if(inputData.country.length > 0 &amp;&amp; !inputData.country.match(\/^[a-z|A-Z][a-z|A-Z]$\/)) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0errorMsg +=\"Country code must be two letters.\\n\"\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0if(errorMsg.length == 0){\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return true;\n\u00a0\u00a0\u00a0\u00a0} else {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0alert(errorMsg);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return false;\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0}\n}\nexport default Validator;\n<\/pre>\n\n\n\n<p><strong>src\/item-details.js \u2013 viewing item details:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import React, { Component } from 'react';\nimport '.\/App.css';\nclass ItemDetails extends Component {\n\u00a0\u00a0constructor(props) {\n\u00a0\u00a0\u00a0\u00a0super(props);\n\u00a0\u00a0\u00a0\u00a0this.onEdit = this.onEdit.bind(this);\n\u00a0\u00a0\u00a0\u00a0this.onDelete = this.onDelete.bind(this);\n\u00a0\u00a0}\n\u00a0\u00a0render() {\n\u00a0\u00a0\u00a0\u00a0const item = this.props.item;\n\u00a0\u00a0\u00a0\u00a0return (\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"input-panel\">\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;span className=\"form-caption\">{ item.name}&lt;\/span>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div>&lt;span className=\"field-name\">Name:&lt;\/span>&lt;br\/> {item.name}&lt;\/div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div>&lt;span className=\"field-name\">Summary:&lt;\/span>&lt;br\/> {item.summary}&lt;\/div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div>&lt;span className=\"field-name\">Year:&lt;\/span>&lt;br\/> {item.year}&lt;\/div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div>&lt;span className=\"field-name\">Country:&lt;\/span>&lt;br\/> {item.country}&lt;\/div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div>&lt;span className=\"field-name\">Description:&lt;\/span>&lt;br\/> {item.description}&lt;\/div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;br\/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;button onClick={() => this.onDelete()}>Delete&lt;\/button>\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;button onClick={() => this.onEdit()}>Edit&lt;\/button>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div>\n\u00a0\u00a0\u00a0\u00a0);\n\u00a0\u00a0}\n\u00a0\u00a0onEdit() {\n\u00a0\u00a0\u00a0\u00a0this.props.onEdit();\n\u00a0\u00a0}\n\u00a0\u00a0onDelete() {\n\u00a0\u00a0\u00a0\u00a0const item = this.props.item;\n\u00a0\u00a0\u00a0\u00a0if(window.confirm(\"Are you sure you want to delete item: \" + item.name + \" ?\")) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.props.onDelete(item.link);\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0}\n}\nexport default ItemDetails;\n<\/pre>\n\n\n\n<p><strong>src\/edit-item.js \u2013 editing existing items:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import React, { Component } from 'react';\nimport '.\/App.css';\nimport Validator from '.\/shared\/validator';\nclass EditItem extends Component {\n\u00a0\u00a0constructor(props) {\n\u00a0\u00a0\u00a0\u00a0super(props);\n\u00a0\u00a0\u00a0\u00a0this.validator = new Validator();\n\u00a0\u00a0\u00a0\u00a0this.onCancel = this.onCancel.bind(this);\n\u00a0\u00a0\u00a0\u00a0this.onSubmit = this.onSubmit.bind(this);\n\u00a0\u00a0\u00a0\u00a0this.handleInputChange = this.handleInputChange.bind(this);\n\u00a0\u00a0\u00a0\u00a0const itemToEdit = props.item;\n\u00a0\u00a0\u00a0\u00a0this.state = {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name: itemToEdit.name,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0summary: itemToEdit.summary,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0year: itemToEdit.year,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0country: itemToEdit.country,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0description: itemToEdit.description,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0link: itemToEdit.link\n\u00a0\u00a0\u00a0\u00a0};\n\u00a0\u00a0}\n\u00a0\u00a0handleInputChange(event) {\n\u00a0\u00a0\u00a0\u00a0const target = event.target;\n\u00a0\u00a0\u00a0\u00a0const value = target.value;\n\u00a0\u00a0\u00a0\u00a0const name = target.name;\n\u00a0\u00a0\u00a0\u00a0this.setState({\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0[name]: value\n\u00a0\u00a0\u00a0\u00a0});\n\u00a0\u00a0}\n\u00a0\u00a0onCancel() {\n\u00a0\u00a0\u00a0\u00a0this.props.onCancel();\n\u00a0\u00a0}\n\u00a0\u00a0onSubmit() {\n\u00a0\u00a0\u00a0\u00a0if (this.validator.validateInputs(this.state)) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.props.onSubmit(this.state);\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0}\n\u00a0\u00a0render() {\n\u00a0\u00a0\u00a0\u00a0return (\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"input-panel\">\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;span className=\"form-caption\">Edit item:&lt;\/span> &lt;span>{this.state.name}&lt;\/span>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;label className=\"field-name\">Name:&lt;br\/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input value={this.state.name} name=\"name\" maxLength=\"40\" required onChange={this.handleInputChange} placeholder=\"item name\" \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/label>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;label className=\"field-name\">Summary:&lt;br\/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input value={this.state.summary} name=\"summary\" maxLength=\"40\" required onChange={this.handleInputChange} placeholder=\"summary\" \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/label>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;label className=\"field-name\">Year:&lt;br\/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input value={this.state.year} name=\"year\" maxLength=\"4\" pattern=\"[0-9]{1,4}\" onChange={this.handleInputChange} placeholder=\"year\" \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/label>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;label className=\"field-name\">Country:&lt;br\/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input value={this.state.country} name=\"country\" maxLength=\"2\" pattern=\"[a-z|A-Z]{2}\" onChange={this.handleInputChange} placeholder=\"country\" \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/label>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;label className=\"field-name\">Description:&lt;br\/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;textarea value={this.state.description} name=\"description\" onChange={this.handleInputChange} placeholder=\"description\" \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/label>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;br\/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;button onClick={() => this.onCancel()}>Cancel&lt;\/button>\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;button onClick={() => this.onSubmit()}>Update&lt;\/button>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div>\n\u00a0\u00a0\u00a0\u00a0);\n\u00a0\u00a0}\n}\nexport default EditItem;\n<\/pre>\n\n\n\n<p>Here we will use the lifting-state-up approach. Instead of maintaining state in each of the child component and synchronizing their states, and hence the appearance of related components, we will lift the shared state up to their closest common ancestor. So, we can maintain state in the parent app component using callback functions that are passed to child components via properties. Then we will call the callback functions inside event handlers in the child components where we change the parent component state accordingly to the user actions triggered in the child components. For instance, see how theApp.onEditItem() method is called in theItemDetails.onEdit() event handler that is triggered when the user clicks the Edit button.<\/p>\n\n\n\n<p>We have provided all the scripts in place, and so we can see the main application at http:\/\/localhost:3000:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/ydTEF4klIiYyvQ1YP8qafl7-9_YguUWCUJZ2tviID6PvJaHVw_vlK3qL5CN3yAxmbNMOm4DQd9LixHhd62goMSUweBKBQjHBPf0a2hSx6-8wjOmT2259lEIIFEQlte-golVGMlA\" alt=\"React.js application\" width=\"345\" height=\"363\" title=\"\"><\/figure>\n\n\n\n<p>We can see the item details by clicking on an item in the list:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/iPL5T3YAv797pLARg11J2_OtsCmJWpsLk_zYBRmTE65kuUnPDbIk12t146Fhi0LlvPAVywNO0bvZZ4dFTibsrYH2yT4XEIzy4Rgo25pCtGF9texRs_w37KEoWisaNLK52UbpLho\" alt=\"React.js application\" width=\"294\" height=\"453\" title=\"\"><\/figure>\n\n\n\n<p>We can also make the detail view editable with the Edit button, if we need to edit an item:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/0ExRpz82s8WolAnKfDsLNtbJA4H6NiyePiExpYflTm13O5g00ol7-xepmw7QGiJgAZGPyIcDRW6OamBU9d4m9OwD4DRP-q3SN0kguJwlk1TxcKH3jmLRL6uFM0n5dLrmtDc7p90\" alt=\"React.js application\" width=\"343\" height=\"533\" title=\"\"><\/figure>\n\n\n\n<p>We can also add new items with the New Item button:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/QESu5GyHmwdPLKkkTsv70s-UY3UTp24Cqex0RqwJ0oPhSbtZ6Bk9uF5C1odcPScDGCZBU3ftVL7tG9OAslw243RtDlTdxNWKwhvKuFJEobTT7HE2YWpR7iZohqyHKi119sptsoA\" alt=\"React.js application\" width=\"292\" height=\"511\" title=\"\"><\/figure>\n\n\n\n<p><strong>Step 4:<\/strong> Real Communication<\/p>\n\n\n\n<p>While React does not provide any built-in support for sending requests to the server, we can freely use any communication library inside our React applications. Let us use the Fetch API, which is becoming a standard way to send HTTP requests and is supported in almost modern browsers. We have provided our communication interface defined, and so we can easily substitute our mock service implementation with a fully functional version, like the following.<\/p>\n\n\n\n<p><strong>src\/shared\/item-service,js \u2013 functional version of ItemService:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import Configuration from '.\/configuration';\nclass ItemService {\n\u00a0\u00a0constructor() {\n\u00a0\u00a0\u00a0\u00a0this.config = new Configuration();\n\u00a0\u00a0}\n\u00a0\u00a0async retrieveItems() {\n\u00a0\u00a0\u00a0\u00a0return fetch(this.config.ITEM_COLLECTION_URL)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.then(response => {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (!response.ok) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.handleResponseError(response);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return response.json();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0})\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.then(json => {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0console.log(\"Retrieved items:\");\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0console.log(json);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const items = [];\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const itemArray = json._embedded.collectionItems;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0for(var i = 0; i &lt; itemArray.length; i++) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0itemArray[i][\"link\"] =\u00a0 itemArray[i]._links.self.href;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0items.push(itemArray[i]);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return items;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0})\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.catch(error => {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.handleError(error);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});\n\u00a0\u00a0}\n\u00a0\u00a0async getItem(itemLink) {\n\u00a0\u00a0\u00a0\u00a0console.log(\"ItemService.getItem():\");\n\u00a0\u00a0\u00a0\u00a0console.log(\"Item: \" + itemLink);\n\u00a0\u00a0\u00a0\u00a0return fetch(itemLink)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.then(response => {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (!response.ok) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.handleResponseError(response);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return response.json();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0})\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.then(item => {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0item[\"link\"] = item._links.self.href;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return item;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.catch(error => {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.handleError(error);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});\n\u00a0\u00a0}\n\u00a0\u00a0async createItem(newitem) {\n\u00a0\u00a0\u00a0\u00a0console.log(\"ItemService.createItem():\");\n\u00a0\u00a0\u00a0\u00a0console.log(newitem);\n\u00a0\u00a0\u00a0\u00a0return fetch(this.config.ITEM_COLLECTION_URL, {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0method: \"POST\",\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0mode: \"cors\",\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0headers: {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Content-Type\": \"application\/json\"\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0body: JSON.stringify(newitem)\n\u00a0\u00a0\u00a0\u00a0})\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.then(response => {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (!response.ok) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.handleResponseError(response);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return response.json();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0})\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.catch(error => {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.handleError(error);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});\n\u00a0\u00a0}\n\u00a0\u00a0async deleteItem(itemlink) {\n\u00a0\u00a0\u00a0\u00a0console.log(\"ItemService.deleteItem():\");\n\u00a0\u00a0\u00a0\u00a0console.log(\"item: \" + itemlink);\n\u00a0\u00a0\u00a0\u00a0return fetch(itemlink, {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0method: \"DELETE\",\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0mode: \"cors\"\n\u00a0\u00a0\u00a0\u00a0})\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.then(response => {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (!response.ok) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.handleResponseError(response);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0})\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.catch(error => {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.handleError(error);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});\n\u00a0\u00a0}\n\u00a0\u00a0async updateItem(item) {\n\u00a0\u00a0\u00a0\u00a0console.log(\"ItemService.updateItem():\");\n\u00a0\u00a0\u00a0\u00a0console.log(item);\n\u00a0\u00a0\u00a0\u00a0return fetch(item.link, {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0method: \"PUT\",\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0mode: \"cors\",\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0headers: {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Content-Type\": \"application\/json\"\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0body: JSON.stringify(item)\n\u00a0\u00a0\u00a0\u00a0})\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.then(response => {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (!response.ok) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.handleResponseError(response);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return response.json();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0})\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.catch(error => {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.handleError(error);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});\n\u00a0\u00a0}\n\u00a0\u00a0handleResponseError(response) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0throw new Error(\"HTTP error, status = \" + response.status);\n\u00a0\u00a0}\n\u00a0\u00a0handleError(error) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0console.log(error.message);\n\u00a0\u00a0}\n}\nexport default ItemService;\n<\/pre>\n\n\n\n<p>Here, we will also follow the single-responsibility principle and put all configuration settings into one object, Configuration that can be imported into all relevant components.<\/p>\n\n\n\n<p><strong>Step 5:<\/strong> Running the Front-End Application<\/p>\n\n\n\n<p>We have provided our backend running on http:\/\/localhost:8080, we can set its URL in the configuration class.<\/p>\n\n\n\n<p><strong>Configuration class \u2013 one-point application configuration:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">class Configuration {\n\u00a0\u00a0ITEM_COLLECTION_URL = \"http:\/\/localhost:8080\/collectionItems\";\n}\nexport default Configuration;\nAnd to start up our application:\n...\/project-root\/consuming-rest>npm start\n<\/pre>\n\n\n\n<p>This time, we can see the main application screen with real data from the backend:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/X5CeTSc8oG4RDJp5koE9iUcb8kIjbNIpeI9sWPJwXPXocgxxzKa8b7Bb4pVCFwL9f843QoN6ZT_15DrRjTDlRybXat1nfd1zXbaFL3VYj7uuGrU0EXSykcgQcJE4fSFyF6dHFd8\" alt=\"React.js application\" width=\"429\" height=\"264\" title=\"\"><\/figure>\n\n\n\n<p>We can also add new items, as the following screenshot illustrates:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/IZLi72ybITFTuZUfUD2qEIJBd7coDBlhZ87f3FtP6gYOKoRlmKc5nlHlODHhYAWN7V2_tsTS0GYHbcyxTVAeh2vo6Ed4CrqvOaMZHheC_MfbcjKrxgpAQzw76hUiI6f1dfr3sFA\" alt=\"React.js application\" width=\"393\" height=\"507\" title=\"\"><\/figure>\n\n\n\n<p>New item added:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/uMtTaKLrHXi9o4P3GAzcdBfr_055QA8Wo1xvRnQTnFvN1Y-pK0F5p6VB75Qp7SoOVH98dnxwjVTZdDtZ-qZLYWPzuBBIkNugFMfB9qgi4W5X5NFbDh9-bnEtI_aASuNNMhqUxRM\" alt=\"React.js application\" width=\"372\" height=\"256\" title=\"\"><\/figure>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>React.js is a lightweight JavaScript framework, which is oriented toward the creation of component-based web UIs. React does not provide any means for communicating with the backend, but we can use any communication library from inside React components. Here we are developing a simple React application consuming the REST API.&nbsp; Step 1: React.js Development Environment [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":8336,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[42],"tags":[],"class_list":["post-8333","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java-tutorials"],"_links":{"self":[{"href":"https:\/\/www.h2kinfosys.com\/blog\/wp-json\/wp\/v2\/posts\/8333","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.h2kinfosys.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.h2kinfosys.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.h2kinfosys.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.h2kinfosys.com\/blog\/wp-json\/wp\/v2\/comments?post=8333"}],"version-history":[{"count":0,"href":"https:\/\/www.h2kinfosys.com\/blog\/wp-json\/wp\/v2\/posts\/8333\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.h2kinfosys.com\/blog\/wp-json\/wp\/v2\/media\/8336"}],"wp:attachment":[{"href":"https:\/\/www.h2kinfosys.com\/blog\/wp-json\/wp\/v2\/media?parent=8333"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.h2kinfosys.com\/blog\/wp-json\/wp\/v2\/categories?post=8333"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.h2kinfosys.com\/blog\/wp-json\/wp\/v2\/tags?post=8333"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}