In this article, we will see how to make an API call to fetch data in react, update the data, create a new record and delete records.
Project setup
First, create a new react app using the following command:
npx create-react-app react-fetch-get-post-put-delete
Now install BlueprintJS for styling the app.
npm i @blueprintjs/core
Add the following styles in index.css
:
@import "~normalize.css";
@import "~@blueprintjs/core/lib/css/blueprint.css";
@import "~@blueprintjs/icons/lib/css/blueprint-icons.css";
body {
display: flex;
justify-content: center;
}
Here we are including the blueprint styles we installed earlier.
GET: Displaying user data
We will use JSON placeholder for the APIs.
import { Button, EditableText } from "@blueprintjs/core"
import { useEffect, useState } from "react"
import "./App.css"
function App() {
const [users, setUsers] = useState([])
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/users")
.then(response => response.json())
.then(json => setUsers(json))
}, [])
return (
<div className="App">
<table class="bp4-html-table .modifier">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Email</th>
<th>Website</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{users.map(user => (
<tr key={user.id}>
<td>{user.id}</td>
<td>{user.name}</td>
<td>
<EditableText value={user.email} />
</td>
<td>
<EditableText value={user.website} />
</td>
<td>
<Button intent="primary">Update</Button>
<Button intent="danger">Delete</Button>
</td>
</tr>
))}
</tbody>
</table>
</div>
)
}
export default App
In the above code,
- We are fetching the list of users inside the useEffect.
- Displaying id, name, email, and website of each user.
- Have 2 action buttons for updating and deleting the user details.
If you run the app now, you will be able to see the list of users:
POST: Adding new user
import "./App.css"
import { useEffect, useState } from "react"
import {
Button,
EditableText,
InputGroup,
Toaster,
Position,
} from "@blueprintjs/core"
const AppToaster = Toaster.create({
position: Position.TOP,
})
function App() {
const [users, setUsers] = useState([])
const [newName, setNewName] = useState("")
const [newEmail, setNewEmail] = useState("")
const [newWebsite, setNewWebsite] = useState("")
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/users")
.then(response => response.json())
.then(json => setUsers(json))
}, [])
const addUser = () => {
const name = newName.trim()
const email = newEmail.trim()
const website = newWebsite.trim()
if (name && email && website) {
fetch("https://jsonplaceholder.typicode.com/users", {
method: "POST",
body: JSON.stringify({
name,
email,
website,
}),
headers: {
"Content-type": "application/json; charset=UTF-8",
},
})
.then(response => response.json())
.then(data => {
setUsers([...users, data])
setNewName("")
setNewEmail("")
setNewWebsite("")
AppToaster.show({
message: "User added successfully",
intent: "success",
timeout: 3000,
})
})
}
}
return (
<div className="App">
<table class="bp4-html-table .modifier">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Email</th>
<th>Website</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{users.map(user => (
<tr key={user.id}>
<td>{user.id}</td>
<td>{user.name}</td>
<td>
<EditableText value={user.email} />
</td>
<td>
<EditableText value={user.website} />
</td>
<td>
<Button intent="primary">Update</Button>
<Button intent="danger">Delete</Button>
</td>
</tr>
))}
</tbody>
<tfoot>
<tr>
<td></td>
<td>
<InputGroup
value={newName}
onChange={e => setNewName(e.target.value)}
placeholder="Add name here..."
/>
</td>
<td>
<InputGroup
placeholder="Add email here..."
value={newEmail}
onChange={e => setNewEmail(e.target.value)}
/>
</td>
<td>
<InputGroup
placeholder="Add website here..."
value={newWebsite}
onChange={e => setNewWebsite(e.target.value)}
/>
</td>
<td>
<Button intent="success" onClick={addUser}>
Add user
</Button>
</td>
</tr>
</tfoot>
</table>
</div>
)
}
export default App
In the above code,
- We have introduced 3 new local states to store name, email, and website.
- We have added input fields to read name, email, and website.
- We have a button with the label 'Add user', when clicked will call the
addUser
function. - The
addUser
function will check if all the values are present, and will call the add user API, which uses the HTTP POST method. - Once the user is added successfully, we append the user to the existing users and display a success message.
If you run the application now, you should be able to add a new user.
PUT: Updating user data
We will use the HTTP PUT method to update the data:
import "./App.css"
import { useEffect, useState } from "react"
import {
Button,
EditableText,
InputGroup,
Toaster,
Position,
} from "@blueprintjs/core"
const AppToaster = Toaster.create({
position: Position.TOP,
})
function App() {
const [users, setUsers] = useState([])
const [newName, setNewName] = useState("")
const [newEmail, setNewEmail] = useState("")
const [newWebsite, setNewWebsite] = useState("")
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/users")
.then(response => response.json())
.then(json => setUsers(json))
}, [])
const addUser = () => {
const name = newName.trim()
const email = newEmail.trim()
const website = newWebsite.trim()
if (name && email && website) {
fetch("https://jsonplaceholder.typicode.com/users", {
method: "POST",
body: JSON.stringify({
name,
email,
website,
}),
headers: {
"Content-type": "application/json; charset=UTF-8",
},
})
.then(response => response.json())
.then(data => {
setUsers([...users, data])
setNewName("")
setNewEmail("")
setNewWebsite("")
AppToaster.show({
message: "User added successfully",
intent: "success",
timeout: 3000,
})
})
}
}
const updateUser = id => {
const user = users.find(user => user.id === id)
fetch(`https://jsonplaceholder.typicode.com/users/${id}`, {
method: "PUT",
body: JSON.stringify(user),
headers: {
"Content-type": "application/json; charset=UTF-8",
},
})
.then(response => response.json())
.then(() => {
AppToaster.show({
message: "User updated successfully",
intent: "success",
timeout: 3000,
})
})
}
const onChangeHandler = (id, key, value) => {
setUsers(values => {
return values.map(item =>
item.id === id ? { ...item, [key]: value } : item
)
})
}
return (
<div className="App">
<table class="bp4-html-table .modifier">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Email</th>
<th>Website</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{users.map(user => (
<tr key={user.id}>
<td>{user.id}</td>
<td>{user.name}</td>
<td>
<EditableText
value={user.email}
onChange={value => onChangeHandler(user.id, "email", value)}
/>
</td>
<td>
<EditableText
value={user.website}
onChange={value => onChangeHandler(user.id, "website", value)}
/>
</td>
<td>
<Button intent="primary" onClick={() => updateUser(user.id)}>
Update
</Button>
<Button intent="danger">Delete</Button>
</td>
</tr>
))}
</tbody>
<tfoot>
<tr>
<td></td>
<td>
<InputGroup
value={newName}
onChange={e => setNewName(e.target.value)}
placeholder="Add name here..."
/>
</td>
<td>
<InputGroup
placeholder="Add email here..."
value={newEmail}
onChange={e => setNewEmail(e.target.value)}
/>
</td>
<td>
<InputGroup
placeholder="Add website here..."
value={newWebsite}
onChange={e => setNewWebsite(e.target.value)}
/>
</td>
<td>
<Button intent="success" onClick={addUser}>
Add user
</Button>
</td>
</tr>
</tfoot>
</table>
</div>
)
}
export default App
In the above code,
- We have a function
onChangeHandler
, which will be called whenever the email and website are edited. - When the user clicks on the update button we are calling the
updateUser
function and passing the user id to it. - In the
updateUser
method, we are filtering the user based on the id passed and calling the API with the PUT method to update the user data to API. - On successful update, we are displaying a success message.
JSONPlaceholder will not actually update or delete the data. It will just respond as if they are done.
DELETE: Deleting user
We will use the HTTP DELETE method to delete a user record.
import "./App.css"
import { useEffect, useState } from "react"
import {
Button,
EditableText,
InputGroup,
Toaster,
Position,
} from "@blueprintjs/core"
const AppToaster = Toaster.create({
position: Position.TOP,
})
function App() {
const [users, setUsers] = useState([])
const [newName, setNewName] = useState("")
const [newEmail, setNewEmail] = useState("")
const [newWebsite, setNewWebsite] = useState("")
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/users")
.then(response => response.json())
.then(json => setUsers(json))
}, [])
const addUser = () => {
const name = newName.trim()
const email = newEmail.trim()
const website = newWebsite.trim()
if (name && email && website) {
fetch("https://jsonplaceholder.typicode.com/users", {
method: "POST",
body: JSON.stringify({
name,
email,
website,
}),
headers: {
"Content-type": "application/json; charset=UTF-8",
},
})
.then(response => response.json())
.then(data => {
setUsers([...users, data])
setNewName("")
setNewEmail("")
setNewWebsite("")
AppToaster.show({
message: "User added successfully",
intent: "success",
timeout: 3000,
})
})
}
}
const updateUser = id => {
const user = users.find(user => user.id === id)
fetch(`https://jsonplaceholder.typicode.com/users/${id}`, {
method: "PUT",
body: JSON.stringify(user),
headers: {
"Content-type": "application/json; charset=UTF-8",
},
})
.then(response => response.json())
.then(() => {
AppToaster.show({
message: "User updated successfully",
intent: "success",
timeout: 3000,
})
})
}
const deleteUser = id => {
fetch(`https://jsonplaceholder.typicode.com/posts/${id}`, {
method: "DELETE",
})
.then(response => response.json())
.then(() => {
setUsers(values => {
return values.filter(item => item.id !== id)
})
AppToaster.show({
message: "User deleted successfully",
intent: "success",
timeout: 3000,
})
})
}
const onChangeHandler = (id, key, value) => {
setUsers(values => {
return values.map(item =>
item.id === id ? { ...item, [key]: value } : item
)
})
}
return (
<div className="App">
<table class="bp4-html-table .modifier">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Email</th>
<th>Website</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{users.map(user => (
<tr key={user.id}>
<td>{user.id}</td>
<td>{user.name}</td>
<td>
<EditableText
value={user.email}
onChange={value => onChangeHandler(user.id, "email", value)}
/>
</td>
<td>
<EditableText
value={user.website}
onChange={value => onChangeHandler(user.id, "website", value)}
/>
</td>
<td>
<Button intent="primary" onClick={() => updateUser(user.id)}>
Update
</Button>
<Button intent="danger" onClick={() => deleteUser(user.id)}>
Delete
</Button>
</td>
</tr>
))}
</tbody>
<tfoot>
<tr>
<td></td>
<td>
<InputGroup
value={newName}
onChange={e => setNewName(e.target.value)}
placeholder="Add name here..."
/>
</td>
<td>
<InputGroup
placeholder="Add email here..."
value={newEmail}
onChange={e => setNewEmail(e.target.value)}
/>
</td>
<td>
<InputGroup
placeholder="Add website here..."
value={newWebsite}
onChange={e => setNewWebsite(e.target.value)}
/>
</td>
<td>
<Button intent="success" onClick={addUser}>
Add user
</Button>
</td>
</tr>
</tfoot>
</table>
</div>
)
}
export default App
In the code above,
- We have added the
deleteUser
function, which will be called when the user clicks on the Delete button. - The
deleteUser
function will receive the id of the user to be deleted and will call the API with the HTTP DELETE method. - Once the user is deleted, it will remove the particular user from the users state and display a success message.
Source code and Demo
You can view the complete source code here and a demo here.
Top comments (0)