Skip to content
react

React fetch example - GET/POST/PUT/DELETE with API

Dec 13, 2022Abhishek EH8 Min Read
React fetch example - GET/POST/PUT/DELETE with API

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:

1npx create-react-app react-fetch-get-post-put-delete

Now install BlueprintJS for styling the app.

1npm i @blueprintjs/core

Add the following styles in index.css:

index.css
1@import "~normalize.css";
2@import "~@blueprintjs/core/lib/css/blueprint.css";
3@import "~@blueprintjs/icons/lib/css/blueprint-icons.css";
4
5body {
6 display: flex;
7 justify-content: center;
8}

Here we are including the blueprint styles we installed earlier.

GET: Displaying user data

We will use JSON placeholder for the APIs.

App.js
1import { Button, EditableText } from "@blueprintjs/core"
2import { useEffect, useState } from "react"
3import "./App.css"
4
5function App() {
6 const [users, setUsers] = useState([])
7
8 useEffect(() => {
9 fetch("https://jsonplaceholder.typicode.com/users")
10 .then(response => response.json())
11 .then(json => setUsers(json))
12 }, [])
13
14 return (
15 <div className="App">
16 <table class="bp4-html-table .modifier">
17 <thead>
18 <tr>
19 <th>Id</th>
20 <th>Name</th>
21 <th>Email</th>
22 <th>Website</th>
23 <th>Action</th>
24 </tr>
25 </thead>
26 <tbody>
27 {users.map(user => (
28 <tr key={user.id}>
29 <td>{user.id}</td>
30 <td>{user.name}</td>
31 <td>
32 <EditableText value={user.email} />
33 </td>
34 <td>
35 <EditableText value={user.website} />
36 </td>
37 <td>
38 <Button intent="primary">Update</Button>
39 &nbsp;
40 <Button intent="danger">Delete</Button>
41 </td>
42 </tr>
43 ))}
44 </tbody>
45 </table>
46 </div>
47 )
48}
49
50export 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:

user data displayed in a table

POST: Adding new user

App.js
1import "./App.css"
2import { useEffect, useState } from "react"
3import {
4 Button,
5 EditableText,
6 InputGroup,
7 Toaster,
8 Position,
9} from "@blueprintjs/core"
10
11const AppToaster = Toaster.create({
12 position: Position.TOP,
13})
14
15function App() {
16 const [users, setUsers] = useState([])
17 const [newName, setNewName] = useState("")
18 const [newEmail, setNewEmail] = useState("")
19 const [newWebsite, setNewWebsite] = useState("")
20
21 useEffect(() => {
22 fetch("https://jsonplaceholder.typicode.com/users")
23 .then(response => response.json())
24 .then(json => setUsers(json))
25 }, [])
26
27 const addUser = () => {
28 const name = newName.trim()
29 const email = newEmail.trim()
30 const website = newWebsite.trim()
31 if (name && email && website) {
32 fetch("https://jsonplaceholder.typicode.com/users", {
33 method: "POST",
34 body: JSON.stringify({
35 name,
36 email,
37 website,
38 }),
39 headers: {
40 "Content-type": "application/json; charset=UTF-8",
41 },
42 })
43 .then(response => response.json())
44 .then(data => {
45 setUsers([...users, data])
46 setNewName("")
47 setNewEmail("")
48 setNewWebsite("")
49 AppToaster.show({
50 message: "User added successfully",
51 intent: "success",
52 timeout: 3000,
53 })
54 })
55 }
56 }
57
58 return (
59 <div className="App">
60 <table class="bp4-html-table .modifier">
61 <thead>
62 <tr>
63 <th>Id</th>
64 <th>Name</th>
65 <th>Email</th>
66 <th>Website</th>
67 <th>Action</th>
68 </tr>
69 </thead>
70 <tbody>
71 {users.map(user => (
72 <tr key={user.id}>
73 <td>{user.id}</td>
74 <td>{user.name}</td>
75 <td>
76 <EditableText value={user.email} />
77 </td>
78 <td>
79 <EditableText value={user.website} />
80 </td>
81 <td>
82 <Button intent="primary">Update</Button>
83 &nbsp;
84 <Button intent="danger">Delete</Button>
85 </td>
86 </tr>
87 ))}
88 </tbody>
89 <tfoot>
90 <tr>
91 <td></td>
92 <td>
93 <InputGroup
94 value={newName}
95 onChange={e => setNewName(e.target.value)}
96 placeholder="Add name here..."
97 />
98 </td>
99 <td>
100 <InputGroup
101 placeholder="Add email here..."
102 value={newEmail}
103 onChange={e => setNewEmail(e.target.value)}
104 />
105 </td>
106 <td>
107 <InputGroup
108 placeholder="Add website here..."
109 value={newWebsite}
110 onChange={e => setNewWebsite(e.target.value)}
111 />
112 </td>
113 <td>
114 <Button intent="success" onClick={addUser}>
115 Add user
116 </Button>
117 </td>
118 </tr>
119 </tfoot>
120 </table>
121 </div>
122 )
123}
124
125export 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:

1import "./App.css"
2import { useEffect, useState } from "react"
3import {
4 Button,
5 EditableText,
6 InputGroup,
7 Toaster,
8 Position,
9} from "@blueprintjs/core"
10
11const AppToaster = Toaster.create({
12 position: Position.TOP,
13})
14
15function App() {
16 const [users, setUsers] = useState([])
17 const [newName, setNewName] = useState("")
18 const [newEmail, setNewEmail] = useState("")
19 const [newWebsite, setNewWebsite] = useState("")
20
21 useEffect(() => {
22 fetch("https://jsonplaceholder.typicode.com/users")
23 .then(response => response.json())
24 .then(json => setUsers(json))
25 }, [])
26
27 const addUser = () => {
28 const name = newName.trim()
29 const email = newEmail.trim()
30 const website = newWebsite.trim()
31 if (name && email && website) {
32 fetch("https://jsonplaceholder.typicode.com/users", {
33 method: "POST",
34 body: JSON.stringify({
35 name,
36 email,
37 website,
38 }),
39 headers: {
40 "Content-type": "application/json; charset=UTF-8",
41 },
42 })
43 .then(response => response.json())
44 .then(data => {
45 setUsers([...users, data])
46 setNewName("")
47 setNewEmail("")
48 setNewWebsite("")
49 AppToaster.show({
50 message: "User added successfully",
51 intent: "success",
52 timeout: 3000,
53 })
54 })
55 }
56 }
57
58 const updateUser = id => {
59 const user = users.find(user => user.id === id)
60
61 fetch(`https://jsonplaceholder.typicode.com/users/${id}`, {
62 method: "PUT",
63 body: JSON.stringify(user),
64 headers: {
65 "Content-type": "application/json; charset=UTF-8",
66 },
67 })
68 .then(response => response.json())
69 .then(() => {
70 AppToaster.show({
71 message: "User updated successfully",
72 intent: "success",
73 timeout: 3000,
74 })
75 })
76 }
77
78 const onChangeHandler = (id, key, value) => {
79 setUsers(values => {
80 return values.map(item =>
81 item.id === id ? { ...item, [key]: value } : item
82 )
83 })
84 }
85
86 return (
87 <div className="App">
88 <table class="bp4-html-table .modifier">
89 <thead>
90 <tr>
91 <th>Id</th>
92 <th>Name</th>
93 <th>Email</th>
94 <th>Website</th>
95 <th>Action</th>
96 </tr>
97 </thead>
98 <tbody>
99 {users.map(user => (
100 <tr key={user.id}>
101 <td>{user.id}</td>
102 <td>{user.name}</td>
103 <td>
104 <EditableText
105 value={user.email}
106 onChange={value => onChangeHandler(user.id, "email", value)}
107 />
108 </td>
109 <td>
110 <EditableText
111 value={user.website}
112 onChange={value => onChangeHandler(user.id, "website", value)}
113 />
114 </td>
115 <td>
116 <Button intent="primary" onClick={() => updateUser(user.id)}>
117 Update
118 </Button>
119 &nbsp;
120 <Button intent="danger">Delete</Button>
121 </td>
122 </tr>
123 ))}
124 </tbody>
125 <tfoot>
126 <tr>
127 <td></td>
128 <td>
129 <InputGroup
130 value={newName}
131 onChange={e => setNewName(e.target.value)}
132 placeholder="Add name here..."
133 />
134 </td>
135 <td>
136 <InputGroup
137 placeholder="Add email here..."
138 value={newEmail}
139 onChange={e => setNewEmail(e.target.value)}
140 />
141 </td>
142 <td>
143 <InputGroup
144 placeholder="Add website here..."
145 value={newWebsite}
146 onChange={e => setNewWebsite(e.target.value)}
147 />
148 </td>
149 <td>
150 <Button intent="success" onClick={addUser}>
151 Add user
152 </Button>
153 </td>
154 </tr>
155 </tfoot>
156 </table>
157 </div>
158 )
159}
160
161export 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.

1import "./App.css"
2import { useEffect, useState } from "react"
3import {
4 Button,
5 EditableText,
6 InputGroup,
7 Toaster,
8 Position,
9} from "@blueprintjs/core"
10
11const AppToaster = Toaster.create({
12 position: Position.TOP,
13})
14
15function App() {
16 const [users, setUsers] = useState([])
17 const [newName, setNewName] = useState("")
18 const [newEmail, setNewEmail] = useState("")
19 const [newWebsite, setNewWebsite] = useState("")
20
21 useEffect(() => {
22 fetch("https://jsonplaceholder.typicode.com/users")
23 .then(response => response.json())
24 .then(json => setUsers(json))
25 }, [])
26
27 const addUser = () => {
28 const name = newName.trim()
29 const email = newEmail.trim()
30 const website = newWebsite.trim()
31 if (name && email && website) {
32 fetch("https://jsonplaceholder.typicode.com/users", {
33 method: "POST",
34 body: JSON.stringify({
35 name,
36 email,
37 website,
38 }),
39 headers: {
40 "Content-type": "application/json; charset=UTF-8",
41 },
42 })
43 .then(response => response.json())
44 .then(data => {
45 setUsers([...users, data])
46 setNewName("")
47 setNewEmail("")
48 setNewWebsite("")
49 AppToaster.show({
50 message: "User added successfully",
51 intent: "success",
52 timeout: 3000,
53 })
54 })
55 }
56 }
57
58 const updateUser = id => {
59 const user = users.find(user => user.id === id)
60
61 fetch(`https://jsonplaceholder.typicode.com/users/${id}`, {
62 method: "PUT",
63 body: JSON.stringify(user),
64 headers: {
65 "Content-type": "application/json; charset=UTF-8",
66 },
67 })
68 .then(response => response.json())
69 .then(() => {
70 AppToaster.show({
71 message: "User updated successfully",
72 intent: "success",
73 timeout: 3000,
74 })
75 })
76 }
77
78 const deleteUser = id => {
79 fetch(`https://jsonplaceholder.typicode.com/posts/${id}`, {
80 method: "DELETE",
81 })
82 .then(response => response.json())
83 .then(() => {
84 setUsers(values => {
85 return values.filter(item => item.id !== id)
86 })
87 AppToaster.show({
88 message: "User deleted successfully",
89 intent: "success",
90 timeout: 3000,
91 })
92 })
93 }
94
95 const onChangeHandler = (id, key, value) => {
96 setUsers(values => {
97 return values.map(item =>
98 item.id === id ? { ...item, [key]: value } : item
99 )
100 })
101 }
102
103 return (
104 <div className="App">
105 <table class="bp4-html-table .modifier">
106 <thead>
107 <tr>
108 <th>Id</th>
109 <th>Name</th>
110 <th>Email</th>
111 <th>Website</th>
112 <th>Action</th>
113 </tr>
114 </thead>
115 <tbody>
116 {users.map(user => (
117 <tr key={user.id}>
118 <td>{user.id}</td>
119 <td>{user.name}</td>
120 <td>
121 <EditableText
122 value={user.email}
123 onChange={value => onChangeHandler(user.id, "email", value)}
124 />
125 </td>
126 <td>
127 <EditableText
128 value={user.website}
129 onChange={value => onChangeHandler(user.id, "website", value)}
130 />
131 </td>
132 <td>
133 <Button intent="primary" onClick={() => updateUser(user.id)}>
134 Update
135 </Button>
136 &nbsp;
137 <Button intent="danger" onClick={() => deleteUser(user.id)}>
138 Delete
139 </Button>
140 </td>
141 </tr>
142 ))}
143 </tbody>
144 <tfoot>
145 <tr>
146 <td></td>
147 <td>
148 <InputGroup
149 value={newName}
150 onChange={e => setNewName(e.target.value)}
151 placeholder="Add name here..."
152 />
153 </td>
154 <td>
155 <InputGroup
156 placeholder="Add email here..."
157 value={newEmail}
158 onChange={e => setNewEmail(e.target.value)}
159 />
160 </td>
161 <td>
162 <InputGroup
163 placeholder="Add website here..."
164 value={newWebsite}
165 onChange={e => setNewWebsite(e.target.value)}
166 />
167 </td>
168 <td>
169 <Button intent="success" onClick={addUser}>
170 Add user
171 </Button>
172 </td>
173 </tr>
174 </tfoot>
175 </table>
176 </div>
177 )
178}
179
180export 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.

Do follow me on twitter where I post developer insights more often!

© 2024 CodingDeft.Com