0% found this document useful (0 votes)
5 views8 pages

APIs & State Management

This document provides a comprehensive guide on using APIs with React for state management, including setup instructions and code examples. It covers the use of Axios for API calls, the structure of a React application, and CRUD operations for managing user data. Additionally, it addresses common issues such as CORS and offers a testing checklist to ensure functionality.

Uploaded by

akashkkotari
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views8 pages

APIs & State Management

This document provides a comprehensive guide on using APIs with React for state management, including setup instructions and code examples. It covers the use of Axios for API calls, the structure of a React application, and CRUD operations for managing user data. Additionally, it addresses common issues such as CORS and offers a testing checklist to ensure functionality.

Uploaded by

akashkkotari
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

APIs & State Management

Introduction to APIs in React

Key Points:

● API = Application Programming Interface

● In web development, APIs often return JSON data

● React can use APIs to fetch data from servers

● Two common ways:

1. Fetch API (built into browsers)

2. Axios (third-party library, easier syntax, better error handling)

Project setup (one-time)


npx create-react-app react-api-demo
cd react-api-demo
npm install axios
npm start

File structure (recommended)


src/
├── index.js

├── App.js

├── index.css
├── services/

│ ├── api.js # axios instance

│ └── userService.js # functions: getUsers, addUser, updateUser, deleteUser


└── components/
├── UsersList.js

└── UserForm.js

1) src/index.js
(Wraps the app — default Create React App entry)

import React from "react";


import ReactDOM from "react-dom/client";
import App from "./App";
import "./index.css";

const root = ReactDOM.createRoot(document.getElementById("root"));


root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);

2) src/services/api.js
(Axios instance — change baseURL to your API)

import axios from "axios";

const api = axios.create({


baseURL: "https://jsonplaceholder.typicode.com", // change to your backend
headers: {
"Content-Type": "application/json",
},
});

export default api;


3) src/services/userService.js
(Service functions wrapping API calls)

import api from "./api";

export const getUsers = () => api.get("/users");


export const addUser = (user) => api.post("/users", user);
export const updateUser = (id, user) => api.put(`/users/${id}`, user);
export const deleteUser = (id) => api.delete(`/users/${id}`);

Note: jsonplaceholder.typicode.com accepts POST/PUT/DELETE but does not


persist changes — it's good for demos.

4) src/App.js
(App-level state & handlers — lifts state, passes to components)

import React, { useEffect, useState } from "react";


import { getUsers, addUser as addUserApi, updateUser as updateUserApi, deleteUser as
deleteUserApi } from "./services/userService";
import UsersList from "./components/UsersList";
import UserForm from "./components/UserForm";

function App() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [editingUser, setEditingUser] = useState(null);

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

async function fetchUsers() {


try {
setLoading(true);
const res = await getUsers();
setUsers(res.data);
} catch (err) {
setError(err.message || "Error loading users");
} finally {
setLoading(false);
}
}

async function handleAddUser(userData) {


try {
const res = await addUserApi(userData);
// add created user to UI (jsonplaceholder returns created object)
setUsers(prev => [res.data, ...prev]);
} catch (err) {
setError(err.message);
}
}

async function handleUpdateUser(id, userData) {


try {
const res = await updateUserApi(id, userData);
setUsers(prev => prev.map(u => (u.id === id ? res.data : u)));
setEditingUser(null);
} catch (err) {
setError(err.message);
}
}

async function handleDeleteUser(id) {


try {
await deleteUserApi(id);
setUsers(prev => prev.filter(u => u.id !== id));
} catch (err) {
setError(err.message);
}
}

return (
<div style={{ padding: 20 }}>
<h1>React API CRUD Demo</h1>

<UserForm
onAdd={handleAddUser}
editingUser={editingUser}
onUpdate={handleUpdateUser}
onCancel={() => setEditingUser(null)}
/>

{loading ? (
<p>Loading users...</p>
) : error ? (
<p style={{ color: "red" }}>{error}</p>
):(
<UsersList users={users} onEdit={setEditingUser} onDelete={handleDeleteUser} />
)}
</div>
);
}

export default App;

5) src/components/UserForm.js
(Form used for Add and Edit)

import React, { useEffect, useState } from "react";

export default function UserForm({ onAdd, editingUser, onUpdate, onCancel }) {


const [name, setName] = useState("");
const [email, setEmail] = useState("");

useEffect(() => {
if (editingUser) {
setName(editingUser.name || "");
setEmail(editingUser.email || "");
} else {
setName("");
setEmail("");
}
}, [editingUser]);

function handleSubmit(e) {
e.preventDefault();
const payload = { name, email };
if (editingUser) {
onUpdate(editingUser.id, payload);
} else {
onAdd(payload);
}
setName("");
setEmail("");
}
return (
<form onSubmit={handleSubmit} style={{ marginBottom: 16 }}>
<input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Name"
required
style={{ marginRight: 8 }}
/>
<input
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Email"
required
style={{ marginRight: 8 }}
/>
<button type="submit">{editingUser ? "Update" : "Add"}</button>
{editingUser && (
<button type="button" onClick={onCancel} style={{ marginLeft: 8 }}>
Cancel
</button>
)}
</form>
);
}

6) src/components/UsersList.js
(Display + Edit/Delete actions)

import React from "react";

export default function UsersList({ users = [], onEdit, onDelete }) {


return (
<table border="1" cellPadding="8" style={{ width: "100%", borderCollapse: "collapse" }}>
<thead>
<tr>
<th style={{ textAlign: "left" }}>ID</th>
<th style={{ textAlign: "left" }}>Name</th>
<th style={{ textAlign: "left" }}>Email</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{users.map((u) => (
<tr key={u.id}>
<td>{u.id}</td>
<td>{u.name}</td>
<td>{u.email}</td>
<td>
<button onClick={() => onEdit(u)} style={{ marginRight: 8 }}>Edit</button>
<button onClick={() => onDelete(u.id)}>Delete</button>
</td>
</tr>
))}
</tbody>
</table>
);
}

Optional: Local fake API with json-server


1. Create db.json:

{
"users": [
{ "id": 1, "name": "Alice", "email": "[email protected]" },
{ "id": 2, "name": "Bob", "email": "[email protected]" }
]
}

2. Start server:

json-server --watch db.json --port 4000

3. Change api.js baseURL to http://localhost:4000.

CORS & common gotchas


● If your backend is on a different domain, ensure it allows CORS (backend must set
headers) or use a proxy during development.

● jsonplaceholder simulates success but won't persist PUT/POST for real persistence.

● Always handle errors and show loading states to users.

Quick testing checklist


1. npm start and open http://localhost:3000

2. The app fetches users (GET) and displays them.

3. Use the form to add a user (POST) — see it added in UI.

4. Click Edit → update → the row should update (PUT).

5. Delete a user → it should disappear (DELETE).

You might also like