0.
[Create-React-App]
ReactJS is a front-end development framework which is also famous in serverless applications. Using JSX and ES6 JavaScript, ReactJS can perform CRUD functions of a normal webapp asynchronously. In this tutorial, we are going to build a basic CRUD webapp using ReactJS. Below are the required installations for building this project:
-
npm with nodejs
- create-react-app package
- parse package
- react-router-dom package
-
BACK4APP: Backend & DB cloud service (similar to Google Firebase)
So to start with, download and install npm from the link above if you don't have. Then we can open the terminal and install
create-react-app
:
npm install create-react-app
Now head to the directory that you wish to construct the new project folder. In this tutorial, we are going to build a webapp for adding, editing, and deleting travel records, say the name of the project folder to be "travelrecord":
create-react-app travelrecord
Once it's done, you will see "Happy hacking!" on the terminal.
Now you may type
cd travelrecord to go into the project folder. At the same time, we can use any text editor to open the project folder
travelrecord
.
1.
[Components]
React combined both front-end views and rendering methods (i.e. Views & Controller in MVC), we define the functions and the front-end structure in a single component instead of separating them. After opening the project folder, there is a
index.js
under
src. This is the main document referring to the
public/index.html
which contains a basic HTML structure and is the only html file we need.

In the
index.js
, it imported the
App.js
at the top of the document.
App.js
is the top component being called at
ReactDOM.render(). You may notice that importing a JS file allow omitting
.js at the end of the file name, such as
'./App' instead of
'./App.js'.
When we have written new components, we will import them into
App.js
and render inside. So the structure of rendering is
index
->
App
-> other components we write.
There are many ways to write a component, such as a single function (e.g. shown in the
App.js
), or a class object which we are going to do. Open
App.js
and replace the content as follow:
import React from 'react';
import logo from './logo.svg';
import './App.css';
class App extends React.Component {
render(){
return(
<div>
<p>Hello World!</p>
</div>
);
};
}
export default App;
Now run the project by typing this in the terminal (inside the project folder):
npm run start
The project will run automatically on your browser at
localhost:3000!
To stop running, press
Ctrl + C
.
2.
[ParseServer Back4App]
As this tutorial is creating a CRUD webapp, we need a database to save and render data, i.e. travel records in this example. Many people would use
Google Firebase, but we are going to use
Back4App. Before that, we have to install a package
parse
using npm, since Back4App use ParseObject.
npm install parse
Head to
Back4App website and create an account. Click
Build new app and give it a name
Travel Records . On the dashboard menu, click
API Reference and look for
Initializing Parse SDK, from which copy the
Application ID and
Javascript Key for later use.

Open
App.js
in text editor and update the content as follow. Make sure to copy and paste the
Application ID and
Javascript Key.
import React from 'react';
import logo from './logo.svg';
import './App.css';
import Parse from 'parse'; //Import parse
class App extends React.Component {
constructor(){
super();
Parse.serverURL = 'https://parseapi.back4app.com';
Parse.initialize(
'PASTE_YOUR_APPLICATION_ID_HERE', // Application ID
'PASTE_YOUR_JAVASCRIPT_KEY_HERE' // Javascript key
);
};
render(){
return(
<div>
<p>Hello World</p>
</div>
);
};
}
export default App;
3.
[Create a travel record]
Now the App is ready to fetch data to and from our Back4App account. First of all, we are going to create a new piece of travel record to the DB. Add a new file
Create.js
under
src folder, which will act as the component to create travel records. Inside this file, we have to do several things:
- Import React
- Make a form for data input
- Make a function to submitting the data to the DB
(actually passing a dummy record to
App.js
for posting)
- Prevent form from refreshing
(i.e. event.preventDefault())
Hence, the
Create.js
looks like this:
import React from 'react';
class Create extends React.Component {
begin = React.createRef();
end = React.createRef();
place = React.createRef();
submit = (e) => {
e.preventDefault();
if (this.begin.current.value !== '' &&
this.end.current.value !== '' &&
this.place.current.value !== '') {
let record = {
begin: this.begin.current.value,
end: this.end.current.value,
place: this.place.current.value
};
this.props.createRecord(record);
}
};
render(){
return(
<form onSubmit={this.submit}>
<label>Begin</label>
<input name='begin' ref={this.begin} type='date' />
<label>End</label>
<input name='end' ref={this.end} type='date' />
<label>Place</label>
<input name='place' ref={this.place} type='text' />
<button type='submit'>Add Record!</button>
</form>
);
};
}
export default Create;
It should be noticed that references are created (i.e.
React.createRef()) to store the input data temporarily, and used in the submit method. This is the way for getting data from
Forms.
Now the dummy record is passed to a function named
createRecord(), which should be shared from
App.js
. So open
App.js
, make a
createRecord method and share to
Create
component as follow:
import React from 'react';
import logo from './logo.svg';
import './App.css';
import Parse from 'parse';
import Create from './Create';
class App extends React.Component {
constructor(){
super();
Parse.serverURL = 'https://parseapi.back4app.com';
'PASTE_YOUR_APPLICATION_ID',
'PASTE_YOUR_JAVASCRIPT_KEY'
);
};
createRecord = (r) =>{
const Travel = Parse.Object.extend('Travel');
const record = new Travel();
record.set('begin', r.begin);
record.set('end', r.end);
record.set('place', r.place);
record.save().then(
(result) => {
console.log(result);
},
(error) => {
console.error(error);
}
);
};
render(){
return(
<div>
<p>Hello World</p>
<Create createRecord={this.createRecord} />
</div>
);
};
}
export default App;
Notice that we share the
createRecord() method by adding an attribute in this line at
App.js
<Create createRecord={this.createRecord} />
Such that the
createRecord() method can be called at
Create.js
as
this.props.createRecord
Run the project again
npm run start

Now, if you input details and submit the form, a new record should be shown in the Back4App DB under class name
Travel.
4.
[State and properties]
After creating a new travel record, you may wish to view it from the web app. Before that, we need to understand how to store data locally in the web app and propagate to other components, i.e.
state.
React can propagate data and methods to child components. Hence, if we define a JSON
state in
App.js
, it can be shared to
Some_Component.js
. By using
setState(), we can save the data in the
state object and shared asynchronously to other components.
To hold all travel records locally, we add a
state object in
App.js
after constructor() method:
constructor(){
super();
Parse.serverURL = 'https://parseapi.back4app.com';
Parse.initialize(
'PASTE_YOUR_APPLICATION_ID',
'PASTE_YOUR_JAVASCRIPT_KEY'
);
};
state = {
records: {}
};
createRecord = (r) => {
//...
};
Then add a new
readRecord() method after
createRecord() to render travel records from DB:
createRecord = (r) => {
//...
};
readRecord = () => {
const Travel = Parse.Object.extend('Travel');
const query = new Parse.Query(Travel);
query.find().then(
(result) => {
let records = JSON.parse(JSON.stringify(result)).sort(
(a,b) => (a.begin>b.begin) ? -1 : 1
);
this.setState({ records }, this.forceUpdate());
},
(error) => {console.error(error)}
);
};
Noticed that the result from DB will be a ParseObject, which I convert into an array and sorted by descending order. After that, the sorted array will be parsed as a JSON again, and saved to the local
state by using
this.setState(). Normally, the way to setState should look like this:
let abc = '123';
this.setState({ records: abc });
But the name of the state object (i.e. 'records') is the same as the variable we used for holding the result, hence we can omit the variable 'records' on the right-hand-side.
Also, we added a callback function
this.forceUpdate() which force the
App.js
to re-render since there is no guarantee that
this.state would sync updated data immediately. More detail can be read here:
Stack Overflow
Now we can share the state object
records and the
readRecord() method to a new component
Read.js
which we will create later. Import
Read.js
at the top of
App.js
:
import Read from './Read';
And add the tag
<Read> after
<Create> in
App.js
with attributes like this:
render(){
return(
<div>
<p>Hello World</p>
<Create createRecord={this.createRecord} />
<br />
<Read readRecord={this.readRecord} records={this.state.records}/>
</div>
);
};
5.
[Read all travel records]
Make a new file named
Read.js
under
src, and it should have the duties as followed:
- call the readRecord() method once this component is mounted (i.e. loaded in the main App)
- Render the state.records shared by the
App.js
So
Read.js
will look like this:
import React from 'react';
import Record from './Record';
class Read extends React.Component {
componentDidMount(){
this.props.readRecord();
};
render(){
return(
<table>
<tbody>
<tr>
<th>Begin</th>
<th>End</th>
<th>Place</th>
</tr>
{Object.keys(this.props.records).map(
k =>
<Record key={k}
detail={this.props.records[k]} />
)}
</tbody>
</table>
);
};
}
export default Read;
In its
render() method, we build a table and render all the records row by row, using Javascript
Object.keys() and
map(). You should notice the curly brackets are used whenever the JavaScript ES6 is residing in HTML.
As you notice, there is another component named
Record
used in this file. Let's create this extra component
Record.js
under
src, and its content as followed:
import React from 'react';
class Record extends React.Component {
detail = this.props.detail;
render(){
return(
<tr>
<td>{this.detail.begin}</td>
<td>{this.detail.end}</td>
<td>{this.detail.place}</td>
</tr>
);
};
}
export default Record;
Therefore, the detail of a single travel record is passed from
Read.js
to
Record.js
and rendered in a table row.

Now on the webbrowser, the travel records that you entered should be shown on the webapp.
Furthermore, we can call the
readRecord() method once a new record is created, so user do not need to refresh the page. Update the
createRecord() in
App.js
createRecord = (r) =>{
const Travel = Parse.Object.extend('Travel');
const record = new Travel();
record.set('begin', r.begin);
record.set('end', r.end);
record.set('place', r.place);
record.save().then(
(result) => { this.readRecord() },
(error) => { console.error(error) };
}
);
};
In next post, we will talk about
Update and
Delete of CRUD.