Step-by-Step Guide to Building Your First React CRUD App

Building Your First React CRUD App

Before learn you can check now demo

In the realm of web development, crafting dynamic applications is key to success. React, a powerful JavaScript library, excels at building user interfaces, especially for single-page applications that require efficient handling of Create, Read, Update, and Delete (CRUD) operations. This guide will take you through the process of building a CRUD app with React, focusing on why React’s ecosystem is perfectly suited for this task.

Understanding CRUD Operations

CRUD operations form the backbone of most web applications, enabling users to create new entries, read and retrieve existing data, update or modify it, and delete entries when they’re no longer needed. With React’s component-based architecture, managing these operations becomes intuitive and modular. Different parts of the app, such as forms for creating data, tables for displaying it, and modals for editing or deleting, can be encapsulated into separate components.

Why Choose React for Your CRUD App

React offers a robust ecosystem with tools like React Router for navigation and React Hooks for state management, making it ideal for implementing complex functionalities. Here are some reasons why React is the go-to choice:

  • Simplified State Management: React’s useState hook simplifies managing the state of your application, ensuring that the UI stays in sync with the app’s state.
  • Component Reusability: React promotes reusable components, which can reduce redundancy and enhance maintainability.
  • Declarative UI: React’s declarative nature allows you to define what the UI should look like at any point in time, ensuring that it updates automatically when the underlying data changes.
  • Rich Ecosystem: A vast ecosystem of libraries and tools, such as React Router and React Bootstrap, facilitates faster development and adds functionalities like routing and form validation.

Setting Up the Development Environment

Installing Node.js and npm

To get started, you’ll need Node.js and npm (Node Package Manager). These tools are essential for running and managing React applications.

  1. Download Node.js: Visit the Node.js website and download the recommended version.
  2. Verify Installation: After installation, run the following commands in your terminal:
node -v
npm -v
Creating a New React Project

With Node.js and npm installed, create a new React project using Create React App:

  1. Create React App: Open your terminal and run:

npx create-react-app my-crud-app
  • Replace my-crud-app with your desired project name.

2. Navigate to the Project Directory:

cd my-crud-app

3. Start the Development Server:

npm start
This command will start the development server and open your app in a browser.

Designing the App Layout

Planning the UI Components

A typical CRUD app includes several components:

1

A typical CRUD app includes several components:
All below files are under the components folder:

  • Common/Common.css
  • Common/Footer.js
  • Common/Header.js
  • Common/Loader.js
  • Layout/Home.js
  • Pages/Carosol.js
  • User/CreateUser.js
  • Pages/EditUser.js
  • Pages/ShowUser.js
  • Pages/User.css
  • Pages/User.js

Common/Common.css

.footer{
    background-color: #000;
    color: #FFF;
    text-align: center;
    padding: 10px 0px;
    font-family: 'Courier New', Courier, monospace;
    font-size: 20px;
}
.loader {
    border: 16px solid #f3f3f3;
    border-radius: 50%;
    border-top: 16px solid #3498db;
    width: 120px;
    height: 120px;
    -webkit-animation: spin 2s linear infinite; /* Safari */
    animation: spin 2s linear infinite;
  }
  
  /* Safari */
  @-webkit-keyframes spin {
    0% { -webkit-transform: rotate(0deg); }
    100% { -webkit-transform: rotate(360deg); }
  }
  
  @keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
  }

  .nav-link{
    font-weight: 600;
    text-transform: uppercase;
  }

Common/Footer.js

import React from 'react'
import './Common.css';
export default function Footer() {
  return (
    <div className='footer'>
        Footer
    </div>
  )
}

Common/Header.js

import React from "react";
import { Link } from "react-router-dom";
import "./Common.css";
export default function Header() {
  return (
    <div>
      <nav className="navbar navbar-expand-sm navbar-dark bg-dark">
        <div className="container-fluid">
          <Link to="/" className="navbar-brand" href="#">
            <span className="navbar-text">React CRUD</span>
          </Link>
          <button
            className="navbar-toggler"
            type="button"
            data-bs-toggle="collapse"
            data-bs-target="#mynavbar"
          >
            <span className="navbar-toggler-icon"></span>
          </button>
          <div className="collapse navbar-collapse" id="mynavbar">
            <ul className="navbar-nav ms-auto">
              <li className="nav-item">
                <Link className="nav-link" to="/">
                  Home
                </Link>
              </li>
              <li className="nav-item">
                <Link className="nav-link" to="create-user">
                  Create User
                </Link>
              </li>
              <li className="nav-item">
                <Link className="nav-link" to="show-user">
                  Show User
                </Link>
              </li>
            </ul>
          </div>
        </div>
      </nav>
    </div>
  );
}

Common/Loader.js

import React from 'react'
import "./Common.css";
export default function Loader() {
  return (
    <div><div class="loader"></div></div>
  )
}

Setting Up Homepage

Layout/Home.js

import React from 'react'
import Carasol from '../Pages/Carosol'
const Home = ()=> {
  return (
    <div>
        <Carasol />
    </div>
  )
}

export default Home

Below is content form homepage Carosol

Pages/Carosol.js

import React from "react";

const Carasol = () => {
  return (
    <>
      <div id="demo" className="carousel slide" data-bs-ride="carousel">
        <div className="carousel-indicators">
          <button
            type="button"
            data-bs-target="#demo"
            data-bs-slide-to="0"
            className="active"
          ></button>
          <button
            type="button"
            data-bs-target="#demo"
            data-bs-slide-to="1"
          ></button>
          <button
            type="button"
            data-bs-target="#demo"
            data-bs-slide-to="2"
          ></button>
        </div>

        <div className="carousel-inner">
          <div className="carousel-item active">
            <img
              src={'https://www.w3schools.com/bootstrap5/la.jpg'}
              alt="Los Angeles"
              className="d-block"
            />
          </div>
          <div className="carousel-item">
            <img
              src={'https://www.w3schools.com/bootstrap5/ny.jpg'}
              alt="Chicago"
              className="d-block"
            />
          </div>
          <div className="carousel-item">
            <img
              src={'https://www.w3schools.com/bootstrap5/chicago.jpg'}
              alt="New York"
              className="d-block"
            />
          </div>
        </div>

        <button
          className="carousel-control-prev"
          type="button"
          data-bs-target="#demo"
          data-bs-slide="prev"
        >
          <span className="carousel-control-prev-icon"></span>
        </button>
        <button
          className="carousel-control-next"
          type="button"
          data-bs-target="#demo"
          data-bs-slide="next"
        >
          <span className="carousel-control-next-icon"></span>
        </button>
      </div>
    </>
  );
};

export default Carasol;

The below code is for add, delete, edit, show, and user functionality. 

User/CreateUser.js

import React, { useState } from 'react'
import {useNavigate } from "react-router-dom";
import Loader from '../Common/Loader';
import './User.css';
const CreateUser = () => {
    const navigate = useNavigate();
    const createUserApi = "http://localhost:3000/user"
    const [error, setError] = useState(null);
    const [isLoading, setIsLoading] = useState(false);
    const [user, setUser] = useState({
        name: "",
        email: "",
        phone: ""
    })

    const handelInput = (event) => {
        event.preventDefault();
        const { name, value } = event.target;
        console.log(name, value)
        setUser({ ...user, [name]: value });
    }

    const handelSubmit = async (event) => {
        event.preventDefault();
        console.log(user)
        try {
            setIsLoading(true);
            const response = await fetch(createUserApi, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify(user),
            });

            if (response.ok) {
                console.log('Form submitted successfully!');
                setUser({name: "",email: "",phone: ""})
                navigate('/show-user');
            } else {
                console.error('Form submission failed!');
            }

        } catch (error) {
            setError(error.message);
        } finally{
            setIsLoading(false);
        }
    }

    return (
        <div className='user-form'>
            <div className='heading'>
            {isLoading && <Loader />}
            {error && <p>Error: {error}</p>}
                <p>User Form</p>
            </div>
            <form onSubmit={handelSubmit}>
                <div className="mb-3">
                    <label for="name" className="form-label">Name</label>
                    <input type="text" className="form-control" id="name" name="name" value={user.name} onChange={handelInput} />
                </div>
                <div className="mb-3 mt-3">
                    <label for="email" className="form-label">Email</label>
                    <input type="email" className="form-control" id="email" name="email" value={user.email} onChange={handelInput} />
                </div>
                <div className="mb-3">
                    <label for="pwd" className="form-label">Phone</label>
                    <input type="text" className="form-control" id="phone" name="phone" value={user.phone} onChange={handelInput} />
                </div>
                <button type="submit" className="btn btn-primary submit-btn">Submit</button>
            </form>
        </div>
    )
}

export default CreateUser

User/EditUser.js

import axios from "axios";
import React, { useEffect, useState } from "react";
import { useParams, useNavigate } from "react-router-dom";
import Loader from "../Common/Loader";
import "./User.css";
const EditUser = () => {
  const [user, setUser] = useState([]);
  const [error, setError] = useState(null);
  const [isLoading, setIsLoading] = useState(false);
  const { id } = useParams();
  const navigate = useNavigate();
  const getUserApi = "http://localhost:3000/user";

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

  const getUser = () => {
    axios
      .get(getUserApi.concat("/") + id)
      .then((item) => {
        setUser(item.data);
      })
      .catch((err) => {
        console.log(err);
      });
  };

  const handelInput = (e) => {
    e.preventDefault();
    const { name, value } = e.target;
    console.log(name, value);
    setUser({ ...user, [name]: value });
  };

  const handelSubmit = (e) => {
    e.preventDefault();

    fetch(getUserApi.concat("/") + id, {
      method: "PUT",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(user),
    })
      .then((response) => {
        if (!response.ok) {
          throw new Error("Network response was not ok");
        }
        return response.json();
      })
      .then((data) => {
        setIsLoading(true);
        navigate("/show-user");
      })
      .catch((error) => {
        setError(error.message);
        setIsLoading(false);
      })
  };

  return (
    <div className="user-form">
      <div className="heading">
      {isLoading && <Loader />}
      {error && <p>Error: {error}</p>}
        <p>Edit Form</p>
      </div>
      <form onSubmit={handelSubmit}>
        <div className="mb-3">
          <label for="name" className="form-label">
            Name
          </label>
          <input
            type="text"
            className="form-control"
            id="name"
            name="name"
            value={user.name}
            onChange={handelInput}
          />
        </div>
        <div className="mb-3 mt-3">
          <label for="email" className="form-label">
            Email
          </label>
          <input
            type="email"
            className="form-control"
            id="email"
            name="email"
            value={user.email}
            onChange={handelInput}
          />
        </div>
        <div className="mb-3">
          <label for="pwd" className="form-label">
            Phone
          </label>
          <input
            type="text"
            className="form-control"
            id="phone"
            name="phone"
            value={user.phone}
            onChange={handelInput}
          />
        </div>
        <button type="submit" className="btn btn-primary submit-btn">
          EDIT
        </button>
      </form>
    </div>
  );
};
export default EditUser;

User/ShowUser.js

import React, { useEffect, useState } from "react";
import axios from "axios";
import { Link } from "react-router-dom";
import Loader from "../Common/Loader";

const ShowUser = () => {
  const showUserApi = "http://localhost:3000/user";

  const [user, setUser] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(null);

  const handelDelete = async (id) => {
    console.log("id : -", id);
    setIsLoading(true);
    try {
      const response = await fetch(showUserApi.concat("/") + id, {
        method: "DELETE",
      });
      if (!response.ok) {
        throw new Error("Failed to delete item");
      }
      setUser(user.filter((item) => item.id !== id));
    } catch (error) {
      setError(error.message);
    } finally {
      setIsLoading(false);
    }
  };

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

  const getUsers = () => {
    axios
      .get(showUserApi)
      .then((res) => {
        setUser(res.data);
      })
      .catch((err) => {
        console.log(err);
      });
  };

  if (user.length < 0) {
    return <h1>no user found</h1>;
  } else {
    return (
      <div className="mt-5">
        {isLoading && <Loader />}
        {error && <p>Error: {error}</p>}
        <table className="table table-striped">
          <thead>
            <tr>
              <th>ID</th>
              <th>Name</th>
              <th>Email</th>
              <th>Phone</th>
              <th>Actions</th>
            </tr>
          </thead>
          <tbody>
            {user?.map((item, i) => {
              return (
                <tr key={i + 1}>
                  <td>{i + 1}</td>
                  <td>{item.name}</td>
                  <td>{item.email}</td>
                  <td>{item.phone}</td>
                  <td>
                    <Link to={`/edit-user/${item.id}`}>
                      <i className="fa fa-pencil" aria-hidden="true"></i>
                    </Link>
                    <Link to={`/user/${item.id}`}>
                      <i className="fa fa-eye" aria-hidden="true"></i>
                    </Link>

                    <i
                      className="fa fa-trash-o"
                      aria-hidden="true"
                      onClick={() => handelDelete(item.id)}
                    ></i>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    );
  }
};

export default ShowUser;

User/User.css

*{
    padding: 0px;
    margin: 0px;
}

.user-form{
    max-width: 500px;
    margin: 0px auto;
 
    padding: 35px 35px 50px 35px;
    margin-top: 50px;
    background-color: #ffffff ;
}

.form-control{
    border-radius: 0px !important;
}
.form-label{
    font-weight: 600;
    font-size: 18px;
}
.submit-btn{
    border-radius: 0px;
    width: 100%;
    margin-top: 15px;
    background-color: #000;
    border: 0px !important;
}
.heading{
    padding: 0px 0px 15px 0px;
    text-align: center;
    text-transform: uppercase;
}
.heading p{
    font-size: 25px !important;
    font-weight: 700;

}
.fa{
    border: 1px solid #000;
    padding: 3px;
    margin-right: 10px;
    background-color: rgb(234, 234, 234);
    color: #000; 
}
.fa-trash-o{
    color: rgb(255, 0, 0);
    border: 1px solid red;
    background-color: #ffffff;
    
}

User/User.js

import axios from "axios";
import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import "./User.css";
const EditUser = () => {
  const [user, setUser] = useState([]);
  const { id } = useParams();
  const getUserApi = "http://localhost:3000/user";

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

  const getUser = () => {
    axios
      .get(getUserApi.concat("/") + id)
      .then((item) => {
        setUser(item.data);
      })
      .catch((err) => {
        console.log(err);
      });
  };

  return (
    <div className="user mt-5">
      <table className="table table-bordered">
    <thead>
      <tr>
        <th>Firstname</th>
        <th>Lastname</th>
        
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Name</td>
        <td>{user.name}</td>
      </tr>
      <tr>
        <td>Email</td>
        <td>{user.email}</td>
      </tr>
      <tr>
        <td>Phone</td>
        <td>{user.phone}</td>
      </tr>
    </tbody>
  </table>
    </div>
  );
};
export default EditUser;

Testing and Debugging the App

Writing Unit Tests

Write tests for your components using Jest and React Testing Library.

db.json

{
  "user": [
    {
      "name": "John",
      "email": "john@example.com",
      "phone": "(555) 555-1234",
      "id": "1"
    },
    {
      "name": "Mary",
      "email": "\tmary@example.com",
      "phone": "(555) 555-1234",
      "id": "2"
    },
    {
      "name": "Dooley",
      "email": "july@example.com",
      "phone": "(555) 555-8521",
      "id": "3"
    },
    {
      "name": "Moe",
      "email": "Moe@example.com",
      "phone": "(555) 555-7410",
      "id": "4"
    },
    {
      "name": "Doe",
      "email": "Doe@example.com",
      "phone": "(555) 555-7896",
      "id": "5"
    }
  ]
}
Debugging Common Issues

Use console logging, the React Developer Tools, and other debugging techniques to identify and fix issues.

Conclusion

Building a CRUD app with React involves understanding key concepts like state management, component architecture, and integration with backend services. By following this guide, you’ve learned how to set up a React project, design a CRUD interface, and connect it to a backend, creating a functional and dynamic web application. As you continue to develop, consider exploring. other article

# Getting Started with Create React App
This project realate to react CRUD
## How to start this project

step 1: git clone https://github.com/kanhajatthap/crud-react-app-master
step 2: npm i
step 3: json-server –watch db.json // http://localhost:3000
step 4:  npm  // http://localhost:3001

View Demo
https://crud-react-app-master.vercel.app/

Share the Post:

Table of Contents

Leave a Reply

Your email address will not be published. Required fields are marked *

Join Our Newsletter