Step 1: Setup Project
npx create-react-app library-crud
cd library-crud
npm install axios
Step 2: Setup JSON Server
Install JSON Server globally (or as dev dependency):
npm install -g json-server
Create a db.json file in the root folder (outside src/):
{
"books": [
{ "id": 1, "title": "Atomic Habits", "author": "James Clear", "year": 2018 },
{ "id": 2, "title": "The Alchemist", "author": "Paulo Coelho", "year": 1988 }
]
}
Run the server:
json-server --watch db.json --port 5000
Your API will run at 👉 http://localhost:5000/books
Step 3: Folder Structure
src/
┣ api/
┃ ┗ bookApi.js
┣ components/
┃ ┣ BookCard.jsx
┃ ┣ BookForm.jsx
┃ ┗ BookList.jsx
┣ App.jsx
┣ index.js
â”— App.css
Step 4: API Handling with Axios (src/api/bookApi.js)
import axios from "axios";
const API = "http://localhost:5000/books";
// GET all books
export const getBooks = async () => {
return await axios.get(API);
};
// GET single book
export const getBook = async (id) => {
return await axios.get(`${API}/${id}`);
};
// POST new book
export const addBook = async (book) => {
return await axios.post(API, book);
};
// PUT update book
export const updateBook = async (id, book) => {
return await axios.put(`${API}/${id}`, book);
};
// DELETE book
export const deleteBook = async (id) => {
return await axios.delete(`${API}/${id}`);
};
*Step 5: Components
*
- BookCard.jsx
import React from "react";
const BookCard = ({ book, onDelete, onEdit }) => {
return (
<div className="p-4 border rounded-lg shadow-md bg-white flex justify-between items-center">
<div>
<h2 className="text-lg font-bold">{book.title}</h2>
<p className="text-gray-600">{book.author} ({book.year})</p>
</div>
<div>
<button
onClick={() => onEdit(book)}
className="px-3 py-1 bg-blue-500 text-white rounded mr-2">
Edit
</button>
<button
onClick={() => onDelete(book.id)}
className="px-3 py-1 bg-red-500 text-white rounded">
Delete
</button>
</div>
</div>
);
};
export default BookCard;
- BookForm.jsx
import React, { useState, useEffect } from "react";
const BookForm = ({ onSubmit, currentBook }) => {
const [book, setBook] = useState({ title: "", author: "", year: "" });
useEffect(() => {
if (currentBook) {
setBook(currentBook);
}
}, [currentBook]);
const handleChange = (e) => {
setBook({ ...book, [e.target.name]: e.target.value });
};
const handleSubmit = (e) => {
e.preventDefault();
onSubmit(book);
setBook({ title: "", author: "", year: "" });
};
return (
<form onSubmit={handleSubmit} className="p-4 bg-gray-100 rounded-lg shadow-md mb-4">
<input
type="text" name="title" placeholder="Title" value={book.title}
onChange={handleChange} className="border p-2 mr-2" required
/>
<input
type="text" name="author" placeholder="Author" value={book.author}
onChange={handleChange} className="border p-2 mr-2" required
/>
<input
type="number" name="year" placeholder="Year" value={book.year}
onChange={handleChange} className="border p-2 mr-2" required
/>
<button type="submit" className="px-4 py-2 bg-green-500 text-white rounded">
{currentBook ? "Update" : "Add"} Book
</button>
</form>
);
};
export default BookForm;
- BookList.jsx
import React, { useEffect, useState } from "react";
import BookCard from "./BookCard";
import BookForm from "./BookForm";
import { getBooks, addBook, updateBook, deleteBook } from "../api/bookApi";
const BookList = () => {
const [books, setBooks] = useState([]);
const [currentBook, setCurrentBook] = useState(null);
const loadBooks = async () => {
const response = await getBooks();
setBooks(response.data);
};
useEffect(() => {
loadBooks();
}, []);
const handleAddOrUpdate = async (book) => {
if (currentBook) {
await updateBook(currentBook.id, book);
setCurrentBook(null);
} else {
await addBook(book);
}
loadBooks();
};
const handleDelete = async (id) => {
await deleteBook(id);
loadBooks();
};
const handleEdit = (book) => {
setCurrentBook(book);
};
return (
<div className="max-w-2xl mx-auto mt-10">
<h1 className="text-2xl font-bold mb-4 text-center">📚 Library Management</h1>
<BookForm onSubmit={handleAddOrUpdate} currentBook={currentBook} />
<div className="space-y-3">
{books.map((book) => (
<BookCard key={book.id} book={book} onDelete={handleDelete} onEdit={handleEdit} />
))}
</div>
</div>
);
};
export default BookList;
Step 6: App.jsx
import React from "react";
import BookList from "./components/BookList";
import "./App.css";
function App() {
return (
<div className="App bg-gray-50 min-h-screen">
<BookList />
</div>
);
}
export default App;
Step 7: Run Project
npm start
and in another terminal:
json-server --watch db.json --port 5000
Here is the output of the above code
Top comments (0)