├── .gitignore
├── README.md
├── package.json
├── public
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
├── react-fetch-example.png
├── src
├── App.css
├── App.js
├── index.css
├── index.js
└── reportWebVitals.js
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React Fetch example with Rest API
2 |
3 | React Client with Fetch API to make CRUD requests to Rest API in that:
4 | - React Fetch GET request: get all Tutorials, get Tutorial by Id, find Tutorial by title
5 | - React Fetch POST request: create new Tutorial
6 | - React Fetch PUT request: update an existing Tutorial
7 | - React Fetch DELETE request: delete a Tutorial, delete all Tutorials
8 |
9 | 
10 |
11 | For instruction, please visit:
12 | > [React Fetch example - Get/Post/Put/Delete with Rest API](https://www.bezkoder.com/react-fetch-example/)
13 |
14 | Related Posts:
15 | > [React + Axios: CRUD example to consume Web API](https://www.bezkoder.com/react-crud-web-api/)
16 |
17 | > [React Table example: CRUD App with react-table v7](https://www.bezkoder.com/react-table-example-hooks-crud/)
18 |
19 | Using Material UI instead of Bootstrap:
20 | > [React Material UI examples with a CRUD Application](https://www.bezkoder.com/react-material-ui-examples-crud/)
21 |
22 | More Practice:
23 | > [React Pagination example](https://www.bezkoder.com/react-pagination-material-ui/)
24 |
25 | > [React File Upload example](https://www.bezkoder.com/react-file-upload-axios/)
26 |
27 | > [React JWT Authentication & Authorization example](https://www.bezkoder.com/react-jwt-auth/)
28 |
29 | > [React + Redux: JWT Authentication & Authorization example](https://www.bezkoder.com/react-redux-jwt-auth/)
30 |
31 | Fullstack with Node Express:
32 | > [React + Node Express + MySQL](https://www.bezkoder.com/react-node-express-mysql/)
33 |
34 | > [React + Node Express + PostgreSQL](https://www.bezkoder.com/react-node-express-postgresql/)
35 |
36 | > [React + Node Express + MongoDB](https://www.bezkoder.com/react-node-express-mongodb-mern-stack/)
37 |
38 | Fullstack with Spring Boot:
39 | > [React + Spring Boot + MySQL](https://www.bezkoder.com/react-spring-boot-crud/)
40 |
41 | > [React + Spring Boot + PostgreSQL](https://www.bezkoder.com/spring-boot-react-postgresql/)
42 |
43 | > [React + Spring Boot + MongoDB](https://www.bezkoder.com/react-spring-boot-mongodb/)
44 |
45 | Fullstack with Django:
46 |
47 | > [React + Django Rest Framework](https://www.bezkoder.com/django-react-axios-rest-framework/)
48 |
49 | Serverless:
50 | > [React Firebase CRUD App with Realtime Database](https://www.bezkoder.com/react-firebase-crud/)
51 |
52 | > [React Firestore CRUD App example | Firebase Cloud Firestore](https://www.bezkoder.com/react-firestore-crud/)
53 |
54 | Integration (run back-end & front-end on same server/port)
55 | > [How to integrate React with Spring Boot](https://www.bezkoder.com/integrate-reactjs-spring-boot/)
56 |
57 | > [Integrate React with Node Express on same Server/Port](https://www.bezkoder.com/integrate-react-express-same-server-port/)
58 |
59 |
60 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-fetch-example",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.11.4",
7 | "@testing-library/react": "^11.1.0",
8 | "@testing-library/user-event": "^12.1.10",
9 | "react": "^17.0.2",
10 | "react-dom": "^17.0.2",
11 | "react-scripts": "4.0.3",
12 | "web-vitals": "^1.0.1"
13 | },
14 | "scripts": {
15 | "start": "react-scripts start",
16 | "build": "react-scripts build",
17 | "test": "react-scripts test",
18 | "eject": "react-scripts eject"
19 | },
20 | "eslintConfig": {
21 | "extends": [
22 | "react-app",
23 | "react-app/jest"
24 | ]
25 | },
26 | "browserslist": {
27 | "production": [
28 | ">0.2%",
29 | "not dead",
30 | "not op_mini all"
31 | ],
32 | "development": [
33 | "last 1 chrome version",
34 | "last 1 firefox version",
35 | "last 1 safari version"
36 | ]
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bezkoder/react-fetch-example/7c0ba7623e493cfc8da8874e6a31c941bcc9f026/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
14 |
15 |
19 | React Fetch example
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bezkoder/react-fetch-example/7c0ba7623e493cfc8da8874e6a31c941bcc9f026/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bezkoder/react-fetch-example/7c0ba7623e493cfc8da8874e6a31c941bcc9f026/public/logo512.png
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/react-fetch-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bezkoder/react-fetch-example/7c0ba7623e493cfc8da8874e6a31c941bcc9f026/react-fetch-example.png
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | #app {
2 | max-width: 600px;
3 | }
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { useRef, useState } from "react";
2 | import './App.css';
3 |
4 | function App() {
5 | const baseURL = "http://localhost:8080/api";
6 |
7 | const get_id = useRef(null);
8 | const get_title = useRef(null);
9 |
10 | const post_title = useRef(null);
11 | const post_description = useRef(null);
12 |
13 | const put_id = useRef(null);
14 | const put_title = useRef(null);
15 | const put_description = useRef(null);
16 | const put_published = useRef(null);
17 |
18 | const delete_id = useRef(null);
19 |
20 | const [getResult, setGetResult] = useState(null);
21 | const [postResult, setPostResult] = useState(null);
22 | const [putResult, setPutResult] = useState(null);
23 | const [deleteResult, setDeleteResult] = useState(null);
24 |
25 | const fortmatResponse = (res) => {
26 | return JSON.stringify(res, null, 2);
27 | }
28 |
29 | async function getAllData() {
30 | try {
31 | const res = await fetch(`${baseURL}/tutorials`);
32 |
33 | if (!res.ok) {
34 | const message = `An error has occured: ${res.status} - ${res.statusText}`;
35 | throw new Error(message);
36 | }
37 |
38 | const data = await res.json();
39 |
40 | const result = {
41 | status: res.status + "-" + res.statusText,
42 | headers: {
43 | "Content-Type": res.headers.get("Content-Type"),
44 | "Content-Length": res.headers.get("Content-Length"),
45 | },
46 | length: res.headers.get("Content-Length"),
47 | data: data,
48 | };
49 |
50 | setGetResult(fortmatResponse(result));
51 | } catch (err) {
52 | setGetResult(err.message);
53 | }
54 | }
55 |
56 | async function getDataById() {
57 | const id = get_id.current.value;
58 |
59 | if (id) {
60 | try {
61 | const res = await fetch(`${baseURL}/tutorials/${id}`);
62 |
63 | if (!res.ok) {
64 | const message = `An error has occured: ${res.status} - ${res.statusText}`;
65 | throw new Error(message);
66 | }
67 |
68 | const data = await res.json();
69 |
70 | const result = {
71 | data: data,
72 | status: res.status,
73 | statusText: res.statusText,
74 | headers: {
75 | "Content-Type": res.headers.get("Content-Type"),
76 | "Content-Length": res.headers.get("Content-Length"),
77 | },
78 | };
79 |
80 | setGetResult(fortmatResponse(result));
81 | } catch (err) {
82 | setGetResult(err.message);
83 | }
84 | }
85 | }
86 |
87 | async function getDataByTitle() {
88 | const title = get_title.current.value;
89 |
90 | if (title) {
91 | try {
92 | // const res = await fetch(`${baseURL}/tutorials?title=${title}`);
93 |
94 | let url = new URL(`${baseURL}/tutorials`);
95 | const params = { title: title };
96 | url.search = new URLSearchParams(params);
97 |
98 | const res = await fetch(url);
99 |
100 | if (!res.ok) {
101 | const message = `An error has occured: ${res.status} - ${res.statusText}`;
102 | throw new Error(message);
103 | }
104 |
105 | const data = await res.json();
106 |
107 | const result = {
108 | status: res.status + "-" + res.statusText,
109 | headers: {
110 | "Content-Type": res.headers.get("Content-Type"),
111 | "Content-Length": res.headers.get("Content-Length"),
112 | },
113 | data: data,
114 | };
115 |
116 | setGetResult(fortmatResponse(result));
117 | } catch (err) {
118 | setGetResult(err.message);
119 | }
120 | }
121 | }
122 |
123 | async function postData() {
124 | const postData = {
125 | title: post_title.current.value,
126 | description: post_description.current.value,
127 | };
128 |
129 | try {
130 | const res = await fetch(`${baseURL}/tutorials`, {
131 | method: "post",
132 | headers: {
133 | "Content-Type": "application/json",
134 | "x-access-token": "token-value",
135 | },
136 | body: JSON.stringify(postData),
137 | });
138 |
139 | if (!res.ok) {
140 | const message = `An error has occured: ${res.status} - ${res.statusText}`;
141 | throw new Error(message);
142 | }
143 |
144 | const data = await res.json();
145 |
146 | const result = {
147 | status: res.status + "-" + res.statusText,
148 | headers: {
149 | "Content-Type": res.headers.get("Content-Type"),
150 | "Content-Length": res.headers.get("Content-Length"),
151 | },
152 | data: data,
153 | };
154 |
155 | setPostResult(fortmatResponse(result));
156 | } catch (err) {
157 | setPostResult(err.message);
158 | }
159 | }
160 |
161 | async function putData() {
162 | const id = put_id.current.value;
163 |
164 | if (id) {
165 | const putData = {
166 | title: put_title.current.value,
167 | description: put_description.current.value,
168 | published: put_published.current.checked,
169 | };
170 |
171 | try {
172 | const res = await fetch(`${baseURL}/tutorials/${id}`, {
173 | method: "put",
174 | headers: {
175 | "Content-Type": "application/json",
176 | "x-access-token": "token-value",
177 | },
178 | body: JSON.stringify(putData),
179 | });
180 |
181 | if (!res.ok) {
182 | const message = `An error has occured: ${res.status} - ${res.statusText}`;
183 | throw new Error(message);
184 | }
185 |
186 | const data = await res.json();
187 |
188 | const result = {
189 | status: res.status + "-" + res.statusText,
190 | headers: { "Content-Type": res.headers.get("Content-Type") },
191 | data: data,
192 | };
193 |
194 | setPutResult(fortmatResponse(result));
195 | } catch (err) {
196 | setPutResult(err.message);
197 | }
198 | }
199 | }
200 |
201 | async function deleteAllData() {
202 | try {
203 | const res = await fetch(`${baseURL}/tutorials`, { method: "delete" });
204 |
205 | const data = await res.json();
206 |
207 | const result = {
208 | status: res.status + "-" + res.statusText,
209 | headers: { "Content-Type": res.headers.get("Content-Type") },
210 | data: data,
211 | };
212 |
213 | setDeleteResult(fortmatResponse(result));
214 | } catch (err) {
215 | setDeleteResult(err.message);
216 | }
217 | }
218 |
219 | async function deleteDataById() {
220 | const id = delete_id.current.value;
221 |
222 | if (id){
223 | try {
224 | const res = await fetch(`${baseURL}/tutorials/${id}`, { method: "delete" });
225 |
226 | const data = await res.json();
227 |
228 | const result = {
229 | status: res.status + "-" + res.statusText,
230 | headers: { "Content-Type": res.headers.get("Content-Type") },
231 | data: data,
232 | };
233 |
234 | setDeleteResult(fortmatResponse(result));
235 | } catch (err) {
236 | setDeleteResult(err.message);
237 | }
238 | }
239 | }
240 |
241 | const clearGetOutput = () => {
242 | setGetResult(null);
243 | }
244 |
245 | const clearPostOutput = () => {
246 | setPostResult(null);
247 | }
248 |
249 | const clearPutOutput = () => {
250 | setPutResult(null);
251 | }
252 |
253 | const clearDeleteOutput = () => {
254 | setDeleteResult(null);
255 | }
256 |
257 | return (
258 |
259 |
React Fetch example
260 |
261 |
262 |
React Fetch GET - BezKoder.com
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 | { getResult &&
}
281 |
282 |
283 |
284 |
285 |
React Fetch POST - BezKoder.com
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 | { postResult &&
}
297 |
298 |
299 |
300 |
301 |
React Fetch PUT - BezKoder.com
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 | { putResult &&
}
320 |
321 |
322 |
323 |
324 |
React Fetch DELETE - BezKoder.com
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 | { deleteResult &&
}
338 |
339 |
340 |
341 |
342 | );
343 | }
344 |
345 | export default App;
346 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | ReactDOM.render(
8 |
9 |
10 | ,
11 | document.getElementById('root')
12 | );
13 |
14 | // If you want to start measuring performance in your app, pass a function
15 | // to log results (for example: reportWebVitals(console.log))
16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17 | reportWebVitals();
18 |
--------------------------------------------------------------------------------
/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------