├── .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 | ![react-query-axios-example](react-query-axios-example.png) 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 |
346 |
{getResult}
347 |
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 |
385 |
{postResult}
386 |
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 |
445 |
{putResult}
446 |
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 | --------------------------------------------------------------------------------