├── .gitignore
├── README.md
├── package.json
├── public
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
├── react-query-axios-example.png
├── src
├── App.css
├── App.js
├── http-common.js
├── index.css
├── index.js
├── logo.svg
└── 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 Query Axios example with Rest API
2 |
3 | React Client with React Query and Axios to make CRUD requests to Rest API in that:
4 |
5 | - React Query Axios GET request: get all Tutorials, get Tutorial by Id, find Tutorial by title
6 | - React Query Axios POST request: create new Tutorial
7 | - React Query Axios PUT request: update an existing Tutorial
8 | - React Query Axios DELETE request: delete a Tutorial, delete all Tutorials
9 |
10 | 
11 |
12 | For instruction, please visit:
13 | > [React Query Axios - Get/Post/Put/Delete example with Rest API](https://www.bezkoder.com/react-query-axios/)
14 |
15 | Related Posts:
16 | > [React Axios example - Get/Post/Put/Delete with Rest API](https://www.bezkoder.com/react-axios-example/)
17 |
18 | > [React Fetch example - Get/Post/Put/Delete with Rest API](https://www.bezkoder.com/react-fetch-example/)
19 |
20 | > [React + Axios: CRUD example to consume Web API](https://www.bezkoder.com/react-crud-web-api/)
21 |
22 | > [React Table example: CRUD App with react-table v7](https://www.bezkoder.com/react-table-example-hooks-crud/)
23 |
24 | Using Material UI instead of Bootstrap:
25 |
26 | > [React Material UI examples with a CRUD Application](https://www.bezkoder.com/react-material-ui-examples-crud/)
27 |
28 | More Practice:
29 |
30 | > [React Pagination example](https://www.bezkoder.com/react-pagination-material-ui/)
31 |
32 | > [React File Upload example](https://www.bezkoder.com/react-file-upload-axios/)
33 |
34 | > [React JWT Authentication & Authorization example](https://www.bezkoder.com/react-jwt-auth/)
35 |
36 | > [React + Redux: JWT Authentication & Authorization example](https://www.bezkoder.com/react-redux-jwt-auth/)
37 |
38 | Fullstack with Node Express:
39 |
40 | > [React + Node Express + MySQL](https://www.bezkoder.com/react-node-express-mysql/)
41 |
42 | > [React + Node Express + PostgreSQL](https://www.bezkoder.com/react-node-express-postgresql/)
43 |
44 | > [React + Node Express + MongoDB](https://www.bezkoder.com/react-node-express-mongodb-mern-stack/)
45 |
46 | Fullstack with Spring Boot:
47 |
48 | > [React + Spring Boot + MySQL](https://www.bezkoder.com/react-spring-boot-crud/)
49 |
50 | > [React + Spring Boot + PostgreSQL](https://www.bezkoder.com/spring-boot-react-postgresql/)
51 |
52 | > [React + Spring Boot + MongoDB](https://www.bezkoder.com/react-spring-boot-mongodb/)
53 |
54 | Fullstack with Django:
55 |
56 | > [React + Django Rest Framework](https://www.bezkoder.com/django-react-axios-rest-framework/)
57 |
58 | Serverless:
59 |
60 | > [React Firebase CRUD App with Realtime Database](https://www.bezkoder.com/react-firebase-crud/)
61 |
62 | > [React Firestore CRUD App example | Firebase Cloud Firestore](https://www.bezkoder.com/react-firestore-crud/)
63 |
64 | Integration (run back-end & front-end on same server/port)
65 |
66 | > [How to integrate React with Spring Boot](https://www.bezkoder.com/integrate-reactjs-spring-boot/)
67 |
68 | > [Integrate React with Node Express on same Server/Port](https://www.bezkoder.com/integrate-react-express-same-server-port/)
69 |
70 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
71 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-query-axios",
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 | "axios": "0.22.0",
10 | "react": "^17.0.2",
11 | "react-dom": "^17.0.2",
12 | "react-query": "^3.29.0",
13 | "react-scripts": "4.0.3",
14 | "web-vitals": "^1.0.1"
15 | },
16 | "scripts": {
17 | "start": "react-scripts start",
18 | "build": "react-scripts build",
19 | "test": "react-scripts test",
20 | "eject": "react-scripts eject"
21 | },
22 | "eslintConfig": {
23 | "extends": [
24 | "react-app",
25 | "react-app/jest"
26 | ]
27 | },
28 | "browserslist": {
29 | "production": [
30 | ">0.2%",
31 | "not dead",
32 | "not op_mini all"
33 | ],
34 | "development": [
35 | "last 1 chrome version",
36 | "last 1 firefox version",
37 | "last 1 safari version"
38 | ]
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bezkoder/react-query-axios-example/7c9d4935195d633e2b5c6932d3d246a841d49e3a/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 |
31 | React Query Axios example
32 |
33 |
34 |
35 |
36 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bezkoder/react-query-axios-example/7c9d4935195d633e2b5c6932d3d246a841d49e3a/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bezkoder/react-query-axios-example/7c9d4935195d633e2b5c6932d3d246a841d49e3a/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-query-axios-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bezkoder/react-query-axios-example/7c9d4935195d633e2b5c6932d3d246a841d49e3a/react-query-axios-example.png
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | #app {
2 | max-width: 600px;
3 | }
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import { useQuery, useMutation } from "react-query";
3 | import "./App.css";
4 |
5 | import apiClient from "./http-common";
6 |
7 | function App() {
8 | const [getId, setGetId] = useState("");
9 | const [getTitle, setGetTitle] = useState("");
10 |
11 | const [postTitle, setPostTitle] = useState("");
12 | const [postDescription, setPostDescription] = useState("");
13 |
14 | const [putId, setPutId] = useState("");
15 | const [putTitle, setPutTitle] = useState("");
16 | const [putDescription, setPutDescription] = useState("");
17 | const [putPublished, setPutPublished] = useState(false);
18 |
19 | const [deleteId, setDeleteId] = useState("");
20 |
21 | const [getResult, setGetResult] = useState(null);
22 | const [postResult, setPostResult] = useState(null);
23 | const [putResult, setPutResult] = useState(null);
24 | const [deleteResult, setDeleteResult] = useState(null);
25 |
26 | const fortmatResponse = (res) => {
27 | return JSON.stringify(res, null, 2);
28 | };
29 |
30 | const { isLoading: isLoadingTutorials, refetch: getAllTutorials } = useQuery(
31 | "query-tutorials",
32 | async () => {
33 | return await apiClient.get("/tutorials");
34 | },
35 | {
36 | enabled: false,
37 | onSuccess: (res) => {
38 | const result = {
39 | status: res.status + "-" + res.statusText,
40 | headers: res.headers,
41 | data: res.data,
42 | };
43 |
44 | setGetResult(fortmatResponse(result));
45 | },
46 | onError: (err) => {
47 | setGetResult(fortmatResponse(err.response?.data || err));
48 | },
49 | }
50 | );
51 |
52 | useEffect(() => {
53 | if (isLoadingTutorials) setGetResult("loading...");
54 | }, [isLoadingTutorials]);
55 |
56 | function getAllData() {
57 | try {
58 | getAllTutorials();
59 | } catch (err) {
60 | setGetResult(fortmatResponse(err));
61 | }
62 | }
63 |
64 | const { isLoading: isLoadingTutorial, refetch: getTutorialById } = useQuery(
65 | "query-tutorial-by-id",
66 | async () => {
67 | return await apiClient.get(`/tutorials/${getId}`);
68 | },
69 | {
70 | enabled: false,
71 | retry: 1,
72 | onSuccess: (res) => {
73 | const result = {
74 | status: res.status + "-" + res.statusText,
75 | headers: res.headers,
76 | data: res.data,
77 | };
78 |
79 | setGetResult(fortmatResponse(result));
80 | },
81 | onError: (err) => {
82 | setGetResult(fortmatResponse(err.response?.data || err));
83 | },
84 | }
85 | );
86 |
87 | useEffect(() => {
88 | if (isLoadingTutorial) setGetResult("loading...");
89 | }, [isLoadingTutorial]);
90 |
91 | function getDataById() {
92 | if (getId) {
93 | try {
94 | getTutorialById();
95 | } catch (err) {
96 | setGetResult(fortmatResponse(err));
97 | }
98 | }
99 | }
100 |
101 | const { isLoading: isSearchingTutorial, refetch: findTutorialsByTitle } =
102 | useQuery(
103 | "query-tutorials-by-title", // ["query-tutorials-by-title", getTitle],
104 | async () => {
105 | return await apiClient.get(`/tutorials?title=${getTitle}`);
106 | },
107 | {
108 | enabled: false,
109 | retry: 1,
110 | onSuccess: (res) => {
111 | const result = {
112 | status: res.status + "-" + res.statusText,
113 | headers: res.headers,
114 | data: res.data,
115 | };
116 |
117 | setGetResult(fortmatResponse(result));
118 | },
119 | onError: (err) => {
120 | setGetResult(fortmatResponse(err.response?.data || err));
121 | },
122 | }
123 | );
124 |
125 | useEffect(() => {
126 | if (isSearchingTutorial) setGetResult("searching...");
127 | }, [isSearchingTutorial]);
128 |
129 | function getDataByTitle() {
130 | if (getTitle) {
131 | try {
132 | findTutorialsByTitle();
133 | } catch (err) {
134 | setGetResult(fortmatResponse(err));
135 | }
136 | }
137 | }
138 |
139 | const { isLoading: isPostingTutorial, mutate: postTutorial } = useMutation(
140 | async () => {
141 | return await apiClient.post(`/tutorials`, {
142 | title: postTitle,
143 | description: postDescription,
144 | });
145 | },
146 | {
147 | onSuccess: (res) => {
148 | const result = {
149 | status: res.status + "-" + res.statusText,
150 | headers: res.headers,
151 | data: res.data,
152 | };
153 |
154 | setPostResult(fortmatResponse(result));
155 | },
156 | onError: (err) => {
157 | setPostResult(fortmatResponse(err.response?.data || err));
158 | },
159 | }
160 | );
161 |
162 | useEffect(() => {
163 | if (isPostingTutorial) setPostResult("posting...");
164 | }, [isPostingTutorial]);
165 |
166 | function postData() {
167 | try {
168 | postTutorial();
169 | } catch (err) {
170 | setPostResult(fortmatResponse(err));
171 | }
172 | }
173 |
174 | const { isLoading: isUpdatingTutorial, mutate: updateTutorial } = useMutation(
175 | async () => {
176 | return await apiClient.put(`/tutorials/${putId}`, {
177 | title: putTitle,
178 | description: putDescription,
179 | published: putPublished,
180 | });
181 | },
182 | {
183 | onSuccess: (res) => {
184 | const result = {
185 | status: res.status + "-" + res.statusText,
186 | headers: res.headers,
187 | data: res.data,
188 | };
189 |
190 | setPutResult(fortmatResponse(result));
191 | },
192 | onError: (err) => {
193 | setPutResult(fortmatResponse(err.response?.data || err));
194 | },
195 | }
196 | );
197 |
198 | useEffect(() => {
199 | if (isUpdatingTutorial) setPutResult("updating...");
200 | }, [isUpdatingTutorial]);
201 |
202 | function putData() {
203 | if (putId) {
204 | try {
205 | updateTutorial();
206 | } catch (err) {
207 | setPutResult(fortmatResponse(err));
208 | }
209 | }
210 | }
211 |
212 | const { isLoading: isDeletingTutorials, mutate: deleteAllTutorials } =
213 | useMutation(
214 | async () => {
215 | return await apiClient.delete("/tutorials/");
216 | },
217 | {
218 | onSuccess: (res) => {
219 | const result = {
220 | status: res.status + "-" + res.statusText,
221 | headers: res.headers,
222 | data: res.data,
223 | };
224 |
225 | setDeleteResult(fortmatResponse(result));
226 | },
227 | onError: (err) => {
228 | setDeleteResult(fortmatResponse(err.response?.data || err));
229 | },
230 | }
231 | );
232 |
233 | useEffect(() => {
234 | if (isDeletingTutorials) setDeleteResult("deleting...");
235 | }, [isDeletingTutorials]);
236 |
237 | function deleteAllData() {
238 | try {
239 | deleteAllTutorials();
240 | } catch (err) {
241 | setDeleteResult(fortmatResponse(err));
242 | }
243 | }
244 |
245 | const { isLoading: isDeletingTutorial, mutate: deleteTutorial } = useMutation(
246 | async () => {
247 | return await apiClient.delete(`/tutorials/${deleteId}`);
248 | },
249 | {
250 | onSuccess: (res) => {
251 | const result = {
252 | status: res.status + "-" + res.statusText,
253 | headers: res.headers,
254 | data: res.data,
255 | };
256 |
257 | setDeleteResult(fortmatResponse(result));
258 | },
259 | onError: (err) => {
260 | setDeleteResult(fortmatResponse(err.response?.data || err));
261 | },
262 | }
263 | );
264 |
265 | useEffect(() => {
266 | if (isDeletingTutorial) setDeleteResult("deleting...");
267 | }, [isDeletingTutorial]);
268 |
269 | function deleteDataById() {
270 | if (deleteId) {
271 | try {
272 | deleteTutorial();
273 | } catch (err) {
274 | setDeleteResult(fortmatResponse(err));
275 | }
276 | }
277 | }
278 |
279 | const clearGetOutput = () => {
280 | setGetResult(null);
281 | };
282 |
283 | const clearPostOutput = () => {
284 | setPostResult(null);
285 | };
286 |
287 | const clearPutOutput = () => {
288 | setPutResult(null);
289 | };
290 |
291 | const clearDeleteOutput = () => {
292 | setDeleteResult(null);
293 | };
294 |
295 | return (
296 |
297 |
React Query Axios example
298 |
299 |
300 |
React Query Axios GET - BezKoder.com
301 |
302 |
303 |
306 |
307 |
setGetId(e.target.value)}
311 | className="form-control ml-2"
312 | placeholder="Id"
313 | />
314 |
315 |
318 |
319 |
320 |
setGetTitle(e.target.value)}
324 | className="form-control ml-2"
325 | placeholder="Title"
326 | />
327 |
328 |
334 |
335 |
336 |
342 |
343 |
344 | {getResult && (
345 |
348 | )}
349 |
350 |
351 |
352 |
353 |
React Query Axios POST - BezKoder.com
354 |
355 |
356 | setPostTitle(e.target.value)}
360 | className="form-control"
361 | placeholder="Title"
362 | />
363 |
364 |
365 | setPostDescription(e.target.value)}
369 | className="form-control"
370 | placeholder="Description"
371 | />
372 |
373 |
376 |
382 |
383 | {postResult && (
384 |
387 | )}
388 |
389 |
390 |
391 |
392 |
React Query Axios PUT - BezKoder.com
393 |
394 |
395 | setPutId(e.target.value)}
399 | className="form-control"
400 | placeholder="Id"
401 | />
402 |
403 |
404 | setPutTitle(e.target.value)}
408 | className="form-control"
409 | placeholder="Title"
410 | />
411 |
412 |
413 | setPutDescription(e.target.value)}
417 | className="form-control"
418 | placeholder="Description"
419 | />
420 |
421 |
422 | setPutPublished(e.target.checked)}
427 | className="form-check-input"
428 | />
429 |
432 |
433 |
436 |
442 |
443 | {putResult && (
444 |
447 | )}
448 |
449 |
450 |
451 |
452 |
453 | React Query Axios DELETE - BezKoder.com
454 |
455 |
456 |
457 |
460 |
461 |
setDeleteId(e.target.value)}
465 | className="form-control ml-2"
466 | placeholder="Id"
467 | />
468 |
469 |
475 |
476 |
477 |
483 |
484 |
485 | {deleteResult && (
486 |
487 |
{deleteResult}
488 |
489 | )}
490 |
491 |
492 |
493 | );
494 | }
495 |
496 | export default App;
497 |
--------------------------------------------------------------------------------
/src/http-common.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 |
3 | export default axios.create({
4 | baseURL: "http://localhost:8080/api",
5 | headers: {
6 | "Content-type": "application/json",
7 | },
8 | });
9 |
--------------------------------------------------------------------------------
/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 | import { QueryClient, QueryClientProvider } from "react-query";
8 | const queryClient = new QueryClient();
9 |
10 | ReactDOM.render(
11 |
12 |
13 |
14 |
15 | ,
16 | document.getElementById('root')
17 | );
18 |
19 | // If you want to start measuring performance in your app, pass a function
20 | // to log results (for example: reportWebVitals(console.log))
21 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
22 | reportWebVitals();
23 |
--------------------------------------------------------------------------------
/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------