Skip to content

Commit 6aa80f8

Browse files
committed
first commit
0 parents  commit 6aa80f8

16 files changed

+2326
-0
lines changed

.gitignore

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
# Editor directories and files
16+
.vscode/*
17+
!.vscode/extensions.json
18+
.idea
19+
.DS_Store
20+
*.suo
21+
*.ntvs*
22+
*.njsproj
23+
*.sln
24+
*.sw?

README.md

+295
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
## React-Query Task Manager - React Fundamental Project 15
2+
3+
This project is a task management application built with React and React Query. It allows users to create, edit, and delete tasks, with data fetching and state management handled by React Query.
4+
5+
**Online Live:**
6+
7+
**Backend-End/Server Source Code:** https://github.com/arnobt78/Task-Management-Server--React-Fundamental-Project-15
8+
9+
## Getting Started
10+
11+
### Prerequisites
12+
13+
- Node.js and npm installed on your machine.
14+
15+
### Installation
16+
17+
1. Clone the repository:
18+
```sh
19+
git clone <repository-url>
20+
```
21+
2. Navigate to the project directory:
22+
```sh
23+
cd react-query-task-manager
24+
```
25+
3. Install the dependencies:
26+
```sh
27+
npm install
28+
```
29+
30+
### Running the Application
31+
32+
1. Start the development server:
33+
```sh
34+
npm run dev
35+
```
36+
2. Open your browser and navigate to `http://localhost:3000`.
37+
38+
## Project Structure
39+
40+
- src
41+
- App.jsx: Main application component.
42+
- Form.jsx: Component for adding new tasks.
43+
- Items.jsx: Component for displaying the list of tasks.
44+
- SingleItem.jsx: Component for displaying a single task.
45+
- reactQueryCustomHooks.jsx: Custom hooks for data fetching and mutations using React Query.
46+
- utils.js: Custom Axios instance for API requests.
47+
- index.css: Global CSS styles.
48+
- main.jsx: Entry point of the application.
49+
50+
## API Endpoints
51+
52+
The application interacts with a backend server to perform CRUD operations on tasks. The base URL for the API is `http://localhost:5000/api/tasks`.
53+
54+
- `GET /`: Fetch all tasks.
55+
- `POST /`: Create a new task.
56+
- `PATCH /:taskId`: Update a task.
57+
- `DELETE /:taskId`: Delete a task.
58+
59+
## Custom Hooks
60+
61+
- `useFetchTasks`: Fetches the list of tasks.
62+
- `useCreateTask`: Creates a new task.
63+
- `useEditTask`: Edits an existing task.
64+
- `useDeleteTask`: Deletes a task.
65+
66+
## Additional Resources
67+
68+
- [React Query Documentation](https://tanstack.com/query/v4/docs/react/overview)
69+
- [Axios Documentation](https://axios-http.com/docs/intro)
70+
71+
## Project Details and Steps
72+
73+
### Server
74+
75+
Open server directory.
76+
77+
- run "npm install" and "npm start"
78+
79+
### Node Course
80+
81+
[Node Tutorial and Projects Course](https://www.udemy.com/course/nodejs-tutorial-and-projects-course/?referralCode=E94792BEAE9ADD204BC7)
82+
83+
### Custom Axios Instance
84+
85+
Create utils.js and setup custom axios instance with
86+
following base url:'http://localhost:5000/api/tasks'
87+
88+
### HTTP Methods
89+
90+
HTTP (Hypertext Transfer Protocol) methods define the types of actions that can be performed on a web server to retrieve, modify or delete information. The most commonly used HTTP methods are GET, POST, PATCH and DELETE. GET retrieves data, POST sends data to be processed, PATCH update or replace existing data, DELETE removes data.
91+
92+
- can use fetch()
93+
94+
GET: This HTTP method is used to retrieve data from a server. When a client sends a GET request to a server, the server will return a response that includes the requested data. This method is typically used to retrieve information from a database, to read a web page, or to download a file. The HTTP GET method is the default method used by web browsers to retrieve data from a server, as it is a safe and efficient way to request resources.
95+
96+
```js
97+
// HTTP GET example
98+
try {
99+
const response = await axios.get("/api/data");
100+
console.log(response.data);
101+
} catch (error) {
102+
console.error(error);
103+
}
104+
```
105+
106+
```js
107+
// HTTP GET example
108+
axios
109+
.get("/api/data")
110+
.then((response) => {
111+
console.log(response.data);
112+
})
113+
.catch((error) => {
114+
console.error(error);
115+
});
116+
```
117+
118+
POST: The POST method is used to send data to a server to create or update a resource. When a client sends a POST request to a server, the server will process the request and create a new resource or update an existing one. This method is commonly used in web forms, where users enter information that is then sent to a server for processing.
119+
120+
```js
121+
// HTTP POST example
122+
try {
123+
const response = await axios.post("/api/data", { name: "John", age: 30 });
124+
console.log(response.data);
125+
} catch (error) {
126+
console.error(error);
127+
}
128+
```
129+
130+
PATCH: This method is similar to the POST method, but it is used to update only a part of a resource. When a client sends a PATCH request to a server, the server will update the resource with the new data provided in the request. This method is commonly used in REST APIs to update specific properties of a resource.
131+
132+
```js
133+
// HTTP PATCH example
134+
try {
135+
const response = await axios.patch("/api/data/1", { age: 31 });
136+
console.log(response.data);
137+
} catch (error) {
138+
console.error(error);
139+
}
140+
```
141+
142+
DELETE: The DELETE method is used to remove a resource from a server. When a client sends a DELETE request to a server, the server will delete the resource if it exists. This method is commonly used in REST APIs to remove a resource that is no longer needed or to undo a previous action.
143+
144+
```js
145+
// HTTP DELETE example
146+
try {
147+
const response = await axios.delete("/api/data/1");
148+
console.log(response.data);
149+
} catch (error) {
150+
console.error(error);
151+
}
152+
```
153+
154+
CRUD stands for Create, Read, Update, and Delete, which are the basic operations that can be performed on a database or web application. These operations allow users to create new data, read existing data, update data, and delete data when necessary.
155+
156+
### Docs
157+
158+
[Task API Docs](https://documenter.getpostman.com/view/18152321/2s93RTSDLn)
159+
160+
### UseEffect Approach
161+
162+
```js
163+
const fetchTasks = async () => {
164+
try {
165+
const response = await customFetch.get("/");
166+
console.log(response.data);
167+
} catch (error) {
168+
+console.error(error);
169+
}
170+
};
171+
172+
useEffect(() => {
173+
fetchTasks();
174+
}, []);
175+
```
176+
177+
### React Query
178+
179+
React Query is a state management library that simplifies the process of fetching, caching, and updating data in React applications. Its major benefits include automatic background refetching, caching and stale data management, error handling, and easy pagination and infinite scrolling. Compared to setting up requests with useEffect, React Query provides a more declarative and centralized approach to managing data in React, which results in cleaner and more efficient code. It also reduces boilerplate code and improves performance by minimizing unnecessary re-renders and network requests.
180+
181+
- tons of features
182+
- versions
183+
184+
[React Query](https://tanstack.com/query/v4/docs/react/overview)
185+
186+
### Install
187+
188+
```sh
189+
npm i @tanstack/react-query
190+
```
191+
192+
### Setup React Query
193+
194+
main.jsx
195+
196+
```js
197+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
198+
const queryClient = new QueryClient();
199+
200+
ReactDOM.createRoot(document.getElementById("root")).render(
201+
<QueryClientProvider client={queryClient}>
202+
<App />
203+
</QueryClientProvider>
204+
);
205+
```
206+
207+
### First Query
208+
209+
Items.jsx
210+
211+
```js
212+
import { useQuery } from "@tanstack/react-query";
213+
214+
const result = useQuery({
215+
queryKey: ["tasks"],
216+
queryFn: () => customFetch.get("/"),
217+
});
218+
console.log(result);
219+
```
220+
221+
- Query Key
222+
223+
The unique key you provide is used internally for refetching, caching, and sharing your queries throughout your application.
224+
225+
- Query Function
226+
227+
A query function can be literally any function that returns a promise. The promise that is returned should either resolve the data or throw an error.
228+
229+
### Error Handling
230+
231+
```js
232+
const Items = () => {
233+
const { isLoading, data, error, isError } = useQuery({
234+
queryKey: ["tasks"],
235+
queryFn: async () => {
236+
const { data } = await customFetch.get("/something");
237+
return data;
238+
},
239+
});
240+
241+
if (isLoading) {
242+
return <p style={{ marginTop: "1rem " }}>Loading...</p>;
243+
}
244+
245+
// if (isError) {
246+
// return <p style={{ marginTop: '1rem ' }}>there was an error...</p>;
247+
// }
248+
if (error) {
249+
return <p style={{ marginTop: "1rem " }}>{error.message}</p>;
250+
}
251+
return (
252+
<div className="items">
253+
{data.taskList.map((item) => {
254+
return <SingleItem key={item.id} item={item} />;
255+
})}
256+
</div>
257+
);
258+
};
259+
export default Items;
260+
```
261+
262+
### Thunder Client Extension
263+
264+
Test API endpoints directly in VS CODE
265+
266+
### Create Task
267+
268+
Form.jsx
269+
270+
```js
271+
const { mutate: createTask, isLoading } = useMutation({
272+
mutationFn: (taskTitle) => customFetch.post("/", { title: taskTitle }),
273+
});
274+
275+
const handleSubmit = (e) => {
276+
e.preventDefault();
277+
createTask(newItemName);
278+
};
279+
```
280+
281+
### useMutation Helper Options
282+
283+
useMutation comes with some helper options that allow quick and easy side-effects at any stage during the mutation lifecycle. These come in handy for both invalidating and refetching queries after mutations
284+
285+
```js
286+
const { mutate: createTask, isLoading } = useMutation({
287+
mutationFn: (taskTitle) => customFetch.post("/", { title: taskTitle }),
288+
onSuccess: () => {
289+
// do something
290+
},
291+
onError: () => {
292+
// do something
293+
},
294+
});
295+
```

index.html

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>React Query</title>
8+
</head>
9+
<body>
10+
<div id="root"></div>
11+
<script type="module" src="/src/main.jsx"></script>
12+
</body>
13+
</html>

0 commit comments

Comments
 (0)