Simple React.js CRUD Example With Rest API


In this post, we will discuss how to perform simple CRUD operations in React.js using a basic HTML table styled with Bootstrap.

CRUD, an acronym derived from the realm of computer programming, refers to the four fundamental operations essential for implementing a storage application: create, read, update, and delete.

Simple React js CRUD Example With Rest API

React JS CRUD example with Rest API

So let’s start React JS CRUD Example — step by step

Step 1

Create react js app using the below command

npx create-react-app crud-app

Step 2

Install bootstrap CSS in our project using the below command

npm install bootstrap –save

Step 3: Rest API for performing Crud operation

1.GET http://samplerestapi.com/api/Tourist

Return list of tourists in the organization, we are going to use this API for binding our table list.

{
"page": 1,
"per_page": 10,
"totalrecord": 8508,
"total_pages": 851,
"data": [
    {
"id": 116597,
"tourist_name": "Johnyt",
"tourist_email": "[email protected]",
"tourist_profilepicture": "http://samplerestapi.com/Media//Images/userimageicon.png",
"tourist_location": "Usa",
"createdat": "2022-05-05T09:32:28.8548478"
    },
    {
"id": 116595,
"tourist_name": "Testing",
"tourist_email": "[email protected]",
"tourist_profilepicture": "http://samplerestapi.com/Media//Images/userimageicon.png",
"tourist_location": "INDIA",
"createdat": "2022-05-05T09:28:33.2964054"
    },
    {
"id": 116592,
"tourist_name": "John",
"tourist_email": "[email protected]",
"tourist_profilepicture": "http://samplerestapi.com/Media//Images/userimageicon.png",
"tourist_location": "Usa",
"createdat": "2022-05-05T09:09:33.4510789"
    },
    {
"id": 116589,
"tourist_name": "John",
"tourist_email": "[email protected]",
"tourist_profilepicture": "http://samplerestapi.com/Media//Images/userimageicon.png",
"tourist_location": "Usa",
"createdat": "2022-05-05T09:03:48.6965879"
    },
    {
"id": 116588,
"tourist_name": "John",
"tourist_email": "[email protected]",
"tourist_profilepicture": "http://samplerestapi.com/Media//Images/userimageicon.png",
"tourist_location": "Usa",
"createdat": "2022-05-05T09:03:24.405684"
    },
    {
"id": 116584,
"tourist_name": "Mikelion",
"tourist_email": "[email protected]",
"tourist_profilepicture": "http://samplerestapi.com/Media//Images/userimageicon.png",
"tourist_location": "lionParis",
"createdat": "2022-05-05T08:35:46.0262257"
    },
    {
"id": 116583,
"tourist_name": "Mikelion",
"tourist_email": "[email protected]",
"tourist_profilepicture": "http://samplerestapi.com/Media//Images/userimageicon.png",
"tourist_location": "lionParis",
"createdat": "2022-05-05T08:26:27.837058"
    },
    {
"id": 116582,
"tourist_name": "testing12121",
"tourist_email": "[email protected]",
"tourist_profilepicture": "http://samplerestapi.com/Media//Images/userimageicon.png",
"tourist_location": "India",
"createdat": "2022-05-05T08:21:24.4612766"
    },
    {
"id": 116580,
"tourist_name": "Mike",
"tourist_email": "[email protected]",
"tourist_profilepicture": "http://samplerestapi.com/Media//Images/userimageicon.png",
"tourist_location": "Paris",
"createdat": "2022-05-05T08:20:33.1709003"
    },
    {
"id": 116575,
"tourist_name": "hello",
"tourist_email": "[email protected]",
"tourist_profilepicture": "http://samplerestapi.com/Media//Images/userimageicon.png",
"tourist_location": "Usa",
"createdat": "2022-05-05T07:30:12.3328337"
    }
  ]
}

2.POST http://samplerestapi.com/api/Tourist

This endpoint is used For making the entry in the database, you need to pass the 3 parameters i.e tourist_nametourist_email, and tourist_location in the request body. 

Request

{
                "tourist_name": "Test user",
                "tourist_email": "[email protected]",
                "tourist_location": "USA"
}

API Response

{
                "$id": "1",
                "id": 15863,
                "tourist_name": "Test user",
                "tourist_email": "[email protected]",
                "tourist_profilepicture": "http://samplerestapi.com/Media//Images/userimageicon.png",
                "tourist_location": "USA",
                "createdat": "2022-01-03T07:53:37.626145Z"
}

 

3. PUT http://samplerestapi.com/api/Tourist/15863

This endpoint is a PUT endpoint and we use that endpoint for updating the record.

API Request

{
                "id": 15863,
                "tourist_name": "Test Update",
                "tourist_email": "[email protected]",
                "tourist_location": "Paris"
}

 

API Response

{
                "$id": "1",
                "id": 15863,
                "tourist_name": "Test Update",
                "tourist_email": "[email protected]",
                "tourist_profilepicture": "http://samplerestapi.com/Media//images/userimageicon.png",
                "tourist_location": "Paris",
                "createdat": "2022-01-03T07:53:37.626145"
}

4.DELETE  http://samplerestapi.com/api/Tourist/15863

This endpoint is used for deleting the record in the database.

Step 5-Create a “httphelpers” folder inside the src folder in our react js project. and add a file inside that folder with the name “restHelper.js”.

helperclass

Copy and paste the below

restHelper.js

export const restHelper = () => {
    
const callAPI = async (endpointurl, options = {}) => {
const defaultHTTPMethod = "GET"
const defaultHTTPHeaders = {  //set defaultHeaders of Http request
"Content-Type": "application/json",
            Accept: "application/json",
        }
const controller = new AbortController() //using  AbortController to cancel ongoing fetch requests
        options.signal = controller.signal

        options.method = options.method || defaultHTTPMethod

        options.headers = options.headers
            ? { ...defaultHTTPHeaders, ...options.headers }
            : defaultHTTPHeaders

        options.body = JSON.stringify(options.body) || false
if (!options.body) delete options.body

        setTimeout(() => { // cancel request if it will take more then 5s 
            controller.abort()
        }, 5000)

try {
const apiResponse = await fetch(endpointurl, options)
            debugger;
return await apiResponse.json()
        } catch (err) {
return err
        }
    }

//calling get API For fetching data
const get = (endpointurl, options = {}) => callAPI(endpointurl, options)

//Post to insert 
const postCreate = (endpointurl, options) => {
        options.method = "POST"
return callAPI(endpointurl, options)
    }


//Put Api calling
const putUpdate = (endpointurl, options) => {
        options.method = "PUT"
return callAPI(endpointurl, options)
    }

//Delete Api calling
const deletedata = (endpointurl, options) => {
        options.method = "DELETE"
return callAPI(endpointurl, options)
    }

return {
get,
        postCreate,
        putUpdate,
        deletedata,
    }
}

I have created the helper class httphelpers/restHelper.jswhich will work as a global helper class and we can utilize that helper in another class or component. using that helper class we will make the different HTTP requests in our application. 

restHelper provides helper functions for making RESTful API calls using the Fetch API in a React.js application. Let's break down the key components of the code:

callAPI: This function is responsible for making the actual API call using the Fetch API. It takes two parameters: endpointurl, which specifies the API endpoint URL, and options, an optional object containing additional configuration options for the API call. It sets default HTTP method and headers, creates an AbortController to cancel ongoing requests, and sets a timeout of 5 seconds to cancel the request if it takes too long. It then performs the fetch operation and returns the API response parsed as JSON.

get: This function specifically for making GET requests. It takes the same parameters as callAPI and forwards them to callAPI with the HTTP method set to GET.

postCreate: This function is used for making POST requests. It takes the parameters as callAPI and forwards them to callAPI with the HTTP method set to POST.

putUpdate:User for making PUT requests. It takes the parameters as callAPI and forwards them to callAPI with the HTTP method set to PUT.

deletedata: This function is user making DELETE requests. 

This module provides a convenient interface for performing CRUD operations (Create, Read, Update, Delete) on a RESTful API in a React.js application by abstracting away the details of making API calls using the Fetch API.

Step 4-Create a “components” folder inside the src folder in our react js project.

Step 4-Right-Click “components” folder ->New File and create the component and I’ll call it Touristtable.js, Crudtourists.js, and Addtourist.js

Components

Touristtable.js

we have created this component, for binding the tourists to the table.

import React from "react"
import Form from "./Addtourist"
import 'bootstrap/dist/css/bootstrap.min.css';

const Touristtable = ({ tourists, postTourist, updateTourist, deleteTourist }) => {
    debugger;
const showUpdateUser = id => {
const form = document.getElementsByClassName(`show-form-${id}`)
        form[0].classList.toggle("hide-form")
    }

const Row = ({ tourist }) => {
return (
            <>
                <div className='row'>
                    <div className='col-sm-2'>{tourist.tourist_name}</div>
                    <div className='col-sm-3'>{tourist.tourist_email}</div>
                    <div className='col-sm-3'>{tourist.tourist_location}</div>
                    <div className='col-sm-4 buttons'>
                        <button className="btn btn-info"  onClick={() => showUpdateUser(tourist.id)}>Update</button>
                        <button  className="btn btn-danger" onClick={() => deleteTourist(tourist.id)}>delete</button>
                    </div>
                </div>
                <div className={`hide-form show-form-${tourist.id}`}>
                    <Form userData={tourist} postTourist={postTourist} updateTourist={updateTourist} />
                </div>
            </>
        )
    }

return (
        <div className='table'>
            <div className='row'>
                <div className='col-sm-2'>Name</div>
                <div className='col-sm-3'>Email</div>
                <div className='col-sm-3'>Location</div>
                <div className='col-sm-4'>Actions</div>
            </div>
            <div className='rows'>
                {tourists && tourists.map(u => <Row tourist={u} key={u.id} />)}
            </div>
        </div>
    )
}

export default Touristtable 
Imports: The component imports necessary modules such as React, the Form component from "./Addtourist" file, and Bootstrap CSS.

Functional Component: Touristtable is a functional component that receives props containing an array of tourist data (tourists), functions for adding (postTourist), updating (updateTourist), and deleting (deleteTourist) tourist records.

Show Update User Function: The showUpdateUser function toggles the visibility of the update form for a particular tourist record when the "Update" button is clicked. It does so by toggling the "hide-form" class on the form element associated with the tourist record.

Row Component: Inside the Touristtable component, there's another functional component called Row. This component represents a single row in the table and receives the tourist data as props. It renders the tourist's name, email, and location in columns, along with "Update" and "Delete" buttons. When the "Update" button is clicked, it triggers the showUpdateUser function to show the update form for the corresponding tourist record.

Rendering: The Touristtable component renders the table structure along with column headers for "Name," "Email," "Location," and "Actions." It then maps through the array of tourist data (tourists) and renders a Row component for each tourist record.

Export: The Touristtable component is exported as the default export, making it available for use in other parts of the application.

This component facilitates the display of tourist data in a table format and provides functionality for updating and deleting tourist records. It also encapsulates the logic for showing the update form for individual tourist records.

Crudtourists.js

we have created this component for rendering Touristtable.js component and showing the list to the user.

import React, { useState, useEffect } from "react"
import Form from "./Addtourist"
import Tablelist from "./Touristtable"
import 'bootstrap/dist/css/bootstrap.min.css';

import { restHelper } from "../httphelpers/restHelper"

const Crudtourists = () => {
const [tourists, settourists] = useState(null)

const url = "http://samplerestapi.com/api/Tourist"
const api = restHelper()

    useEffect(() => {
        gettourists()
    }, [])

const postTourist = tourist => {
        api
            .postCreate(`${url}`, { body: tourist })
            .then(res => gettourists())
            .catch(err => console.log(err))
    }

const updateTourist = (id, tourist) => {
        api
            .putUpdate(`${url}/${id}`, { body: tourist })
            .then(res => gettourists())
            .catch(err => console.log(err))
    }

const deleteTourist = id => {
        api
            .deletedata(`${url}/${id}`, {})
            .then(res => gettourists())
            .catch(err => console.log(err))
    }

const gettourists = () => {
        api
            .get(`${url}`)
            .then(res => {
if(res && res.data)
                {
                    settourists(res.data)
                }
            })
            .catch(err => console.log(err))
    }
if (!tourists) return null

return (
        <>
            <h3>New user</h3>
            <Form postUser={postTourist} />
            <div className='container-fluid'>
                <h3>All users</h3>
                <Tablelist
                    tourists={tourists}
                    settourists={settourists}
                    postTourist={postTourist}
                    updateTourist={updateTourist}
                    deleteTourist={deleteTourist}
                />
            </div>
        </>
    )
}

export default Crudtourists 
 Component Crudtourists, which serves as a container for managing CRUD (Create, Read, Update, Delete) operations for tourist data. Let's discuess the key components of the code:

Imports: The component imports modules such as React, the Form component from "./Addtourist" file, the Tablelist component from "./Touristtable" file, Bootstrap CSS, and the restHelper function from "../httphelpers/restHelper".

Functional Component: Crudtourists is a functional component that uses React's useState and useEffect hooks to manage state and perform side effects respectively.

State Management: The component initializes a state variable tourists using the useState hook to store the tourist data fetched from the API. Initially, it is set to null.

REST API Interaction: The component creates an instance of the REST API helper function restHelper and defines functions postTourist, updateTourist, deleteTourist, and gettourists to perform CRUD operations on the tourist data using the REST API endpoints. These functions utilize methods provided by the restHelper function to make API requests for creating, updating, deleting, and fetching tourist data.

Effect Hook: The useEffect hook is used to fetch the tourist data from the API when the component mounts ([] dependency array ensures that it runs only once).

Conditional Rendering: If tourists state is null, the component returns null to prevent rendering until the tourist data is fetched.

Rendering: Once the tourist data is fetched, the component renders a heading "New user" followed by the Form component for adding new tourists. It then renders a heading "All users" followed by the Tablelist component to display the list of tourists in a table format. The Tablelist component is passed necessary props including tourists data, functions for CRUD operations, and settourists function to update the tourists state.

This component used for managing tourist data by providing user interface elements for adding, viewing, updating, and deleting tourist records. It encapsulates the logic for interacting with the REST API and updating the UI based on the fetched data.   

Addtourist.js

we have created this component for adding the tourist information to the database.

import React, { useState } from "react"


const Addtourist = ({ userData = {}, postUser, updateTourist }) => {
const [user, setUser] = useState({
        id:userData.id ?? 0,
        tourist_name: userData.tourist_name ?? "",
        tourist_email: userData.tourist_email ?? "",
        tourist_location: userData.tourist_location ?? "",
    })

const handleValue = e => {
        setUser({ ...user, [e.target.name]: e.target.value })
    }

const submitUser = e => {
        e.preventDefault()
        debugger;
if (user.tourist_name === "" || user.tourist_email === "" || user.tourist_location === "") return

if (userData.id) {
            debugger;
            updateTourist(userData.id, user)
        } else {
            postUser(user)
        }
        setUser({ ...user, "tourist_name": "","tourist_email": "","tourist_location": "" })
    }

return (
        <form onSubmit={submitUser} className='form-inline'>
            <div className="form-group">
            <input
                type='text'
                name='tourist_name'
                className="form-control"
                value={user.tourist_name}
                placeholder='Name'
                onChange={e => handleValue(e)}
            />
            </div>
            <div className="form-group">
            <input
                type='email'
                name='tourist_email'
                className="form-control"
                value={user.tourist_email}
                placeholder='Email'
                onChange={e => handleValue(e)}
            />
            </div>
            <div className="form-group">
            <input
                type='text'
                name='tourist_location'
                className="form-control"
                value={user.tourist_location}
                placeholder='location..'
                onChange={e => handleValue(e)}
            />
            </div>
            <input
                className='btn btn-primary btnsubmit'
                type='submit'
                value={`${!userData.id ? "Add new user" : "Save user"}`}
            />
        </form>
    )
}

export default Addtourist

Component Addtourist represents a form for adding or updating tourist information. 

Functional Component: Addtourist is a functional component that accepts props containing initial user data (userData), a function for adding new tourists (postUser), and a function for updating existing tourists (updateTourist).

State Management: The component initializes a state variable user using the useState hook to store the tourist data entered in the form fields. The initial state is set based on the userData prop received. If userData is provided, it populates the form fields with the existing tourist data; otherwise, it initializes empty values.

Event Handlers: 

  • handleValue: This function is called when the value of any input field changes. It updates the user state with the new value entered in the respective field.
  • submitUser: This function is called when the form is submitted. It prevents the default form submission behavior, checks if the required fields are filled, and then calls either the postUser function (for adding new tourists) or the updateTourist function (for updating existing tourists) based on whether the userData includes an id. After submission, it clears the form fields.
  • Form Rendering: The component renders a form with input fields for tourist name, email, and location. The values of these fields are controlled by the state variable user. Each input field has an onChange event handler to update the user state when the value changes.

  • Submit Button: The form includes a submit button with dynamic text based on whether it's used for adding a new user or updating an existing user.

This component provides a user-friendly form interface for adding or updating tourist information and encapsulates the logic for handling form submissions and managing state.

Now open App.js file and import Crudtourists.js

import logo from './logo.svg';
import './App.css';
import CrudData from "./components/Crudtourists"
import 'bootstrap/dist/css/bootstrap.min.css';
function App() {
return (
    <div className="container-fluid">
      <main>
                <CrudData />
            </main>
    </div>
  );
}

export default App;

Now let’s run project using below command

npm start

React JS CRUD Example step by step

I’m assuming that you are familiar with React Js framework and creating React Js applications. If not then please go through the following articles: