React CRUD App

Introduction

A CRUD application is one of the most common types of web applications developers build while learning ReactJS. CRUD stands for:

  • Create
  • Read
  • Update
  • Delete

In this tutorial, you will learn how to build a complete CRUD App in React step by step.

What is CRUD?

CRUD represents four basic operations used in applications.

Operation Description
Create Add new data
Read Display data
Update Edit existing data
Delete Remove data

Real-Life Example of CRUD

Student Management System

Operation Example
Create Add student
Read View student list
Update Edit student details
Delete Remove student

Technologies Used

For this React CRUD application, we will use:

  • ReactJS
  • useState Hook
  • useEffect Hook
  • Axios
  • JSON Server (Fake Backend)

Setting Up React Project

Create a React app using Vite or Create React App.

Using Vite


npm create vite@latest

Install dependencies:


npm install

Start development server:


npm run dev

Installing Axios

Axios is used for API requests.


npm install axios

Installing JSON Server

JSON Server creates a fake backend API.


npm install -g json-server

Creating Fake Database

Create a file named:


db.json

Add Sample Data


{
 "users": [
   {
     "id": 1,
     "name": "John"
   },
   {
     "id": 2,
     "name": "David"
   }
 ]
}

Running JSON Server


json-server --watch db.json --port 3000

API URL:


http://localhost:3000/users

Project Structure


src/
├── App.jsx
├── components/
     ├── AddUser.jsx
     ├── UserList.jsx
     ├── EditUser.jsx

Understanding CRUD Flow

Create

Add new data using forms.

Read

Display all users from API.

Update

Edit existing user data.

Delete

Remove user from database.

Building the CRUD App

Step 1: Fetch and Display Users

App.jsx


import { useEffect, useState } from "react";
import axios from "axios";
function App() {
 const [users, setUsers] = useState([]);
 useEffect(() => {
   fetchUsers();
 }, []);
 const fetchUsers = async () => {
   const response = await axios.get(
     "http://localhost:3000/users"
   );
   setUsers(response.data);
 };
 return (
   <div>
     <h1>CRUD App in React</h1>
     {users.map((user) => (
       <div key={user.id}>
         <h2>{user.name}</h2>
       </div>
     ))}
   </div>
 );
}
export default App;

How Read Operation Works?

Step 1

useEffect() runs when component loads.

Step 2

Axios sends GET request.

Step 3

Server returns users data.

Step 4

Users display on screen.

Step 2: Create New User

Add a form for creating users.

Updated App.jsx


import { useEffect, useState } from "react";
import axios from "axios";
function App() {
 const [users, setUsers] = useState([]);
 const [name, setName] = useState("");
 useEffect(() => {
   fetchUsers();
 }, []);
 const fetchUsers = async () => {
   const response = await axios.get(
     "http://localhost:3000/users"
   );
   setUsers(response.data);
 };
 const addUser = async () => {
   if (!name) return;
   await axios.post(
     "http://localhost:3000/users",
     {
       name: name
     }
   );
   setName("");
   fetchUsers();
 };
 return (
   <div>
     <h1>CRUD App</h1>
     <input type="text" placeholder="Enter name" value={name} onChange={(e) => setName(e.target.value) }
     />
     <button onClick={addUser}>
       Add User
     </button>
     {users.map((user) => (
       <div key={user.id}>
         <h2>{user.name}</h2>
       </div>
     ))}
   </div>
 );
}
export default App;

How Create Operation Works?

Step 1

User enters name.

Step 2

Button click triggers addUser().

Step 3

Axios sends POST request.

Step 5

Updated list appears on screen.

Step 3: Delete User

Add delete functionality.

Updated Delete Button


<button
 onClick={() => deleteUser(user.id)}
>
 Delete
</button>

Delete Function


const deleteUser = async (id) => {
 await axios.delete(
   `http://localhost:3000/users/${id}`
 );
 fetchUsers();
};

Complete User Display


{users.map((user) => (
 <div key={user.id}>
   <h2>{user.name}</h2>
   <button
     onClick={() => deleteUser(user.id)}
   >
     Delete
   </button>
 </div>
))}

How Delete Operation Works?

Step 1

User clicks delete button.

Step 2

Axios sends DELETE request.

Step 3

User removes from database.

Step 4

Updated list renders again.

Step 4: Update User

Now add edit functionality.

Add Edit State


const [editingId, setEditingId] =
 useState(null);
const [editName, setEditName] =
 useState("");

Edit Button


<button
 onClick={() => {
   setEditingId(user.id);
   setEditName(user.name);
 }}
>
 Edit
</button>

Update Function


const updateUser = async (id) => {
 await axios.put(
   `http://localhost:3000/users/${id}`,
   {
     name: editName
   }
 );
 setEditingId(null);
 fetchUsers();
};

Edit UI


{editingId === user.id ? (
 <div>
   <input
     type="text"
     value={editName}
     onChange={(e) =>
       setEditName(e.target.value)
     }
   />
   <button
     onClick={() => updateUser(user.id)}
   >
     Save
   </button>
 </div>
) : (
 <div>
   <h2>{user.name}</h2>
   <button
     onClick={() => {
       setEditingId(user.id);
       setEditName(user.name);
     }}
   >
     Edit
   </button>
 </div>
)}

How Update Operation Works?

Step 1

User clicks edit button.

Step 2

Input field appears.

Step 3

User updates name.

Step 4

Axios sends PUT request.

Step 5

Updated data displays instantly.

Final CRUD Flow

Operation HTTP Method
Create POST
Read GET
Update PUT
Delete DELETE

Why CRUD Apps are Important?

CRUD applications help developers learn:

  • React fundamentals
  • API integration
  • State management
  • Form handling
  • Component re-rendering
  • Event handling

CRUD concepts are used in almost every real-world application.

Improving the CRUD App

After building a basic CRUD app, developers can improve it using:

React Router

Add multiple pages.

Context API

Manage global state.

Redux Toolkit

Advanced state management.

Form Validation

Validate user input.

Authentication

Protect CRUD operations.

Tailwind CSS or Bootstrap

Improve UI design.

Adding Loading State

Better user experience.

Example


const [loading, setLoading] =
 useState(true);

Error Handling Example


try {
 const response = await axios.get(url);
} catch (error) {
 console.log(error);
}

Using Async/Await in CRUD App

Async/Await makes code cleaner.

Example


const fetchUsers = async () => {
 const response = await axios.get(url);
 setUsers(response.data);
};

Axios vs Fetch API for CRUD

Feature Axios Fetch API
JSON Parsing Automatic Manual
Error Handling Better Basic
Simplicity Easier Moderate
External Package Yes No

Common Problems While Building CRUD App

Infinite Re-rendering

Incorrect:


useEffect(() => {
 fetchUsers();
});

Correct:


useEffect(() => {
 fetchUsers();
}, []);

Missing Unique Key

Incorrect:


<div>

Correct:


<div key={user.id}>

Not Updating State Properly

Always refresh data after CRUD operations.

Real-Life Use Cases of CRUD Apps

CRUD operations are used in:

  • Banking systems
  • E-commerce websites
  • Hospital management systems
  • School portals
  • Social media platforms
  • Inventory systems
  • Admin dashboards

Best Practices for CRUD Applications

Keep Components Small

Separate form and list components.

Use Proper Folder Structure

Maintain clean code organization.

Handle Errors Properly

Show meaningful error messages.

Use Environment Variables

Store API URLs securely.

Validate User Input

Prevent invalid data submission.

Conclusion

Building a CRUD App in React is one of the best ways to learn modern React development.

In this tutorial, we learned how to:

  • Create data
  • Read data
  • Update data
  • Delete data

CRUD concepts are the foundation of real-world applications, and mastering them is essential for becoming a professional React developer.

Continue Learning React