api 세팅
// src/api/todos.js
import axios from "axios";
const getTodos = async () => {
const response = await axios.get(`${process.env.REACT_APP_SERVER_URL}/todos`);
return response.data;
};
const addTodo = async (newTodo) => {
await axios.post(`${process.env.REACT_APP_SERVER_URL}/todos`, newTodo);
};
const removeTodo = async (id) => {
await axios.delete(`${process.env.REACT_APP_SERVER_URL}/todos/${id}`);
};
const switchTodo = async (payload) => {
await axios.patch(
`${process.env.REACT_APP_SERVER_URL}/todos/${payload.id}`,
payload
);
};
export { getTodos, addTodo, removeTodo, switchTodo };
getTodos는 return문이 꼭 있어야 하고 나머지는 변경하는 역할 이기에 return문을 쓰지않아도 된다.
getTodos
import React from "react";
import Todo from "../Todo";
import { getTodos } from "../../../api/todos";
import { useQuery } from "react-query";
function TodoList({ isActive }) {
const { isLoading, isError, data } = useQuery("todos", getTodos);
if (isLoading) {
return <h1>로딩 중입니다!</h1>;
}
if (isError) {
return <h1>에러 발생!</h1>;
}
return (
<StyledDiv>
<StyledTodoListHeader>
{isActive ? "해야 할 일 ⛱" : "완료한 일 ✅"}
</StyledTodoListHeader>
<StyledTodoListBox>
{data
.filter((item) => item.isDone === !isActive)
.map((item) => {
return <Todo key={item.id} todo={item} isActive={isActive} />;
})}
</StyledTodoListBox>
</StyledDiv>
);
}
export default TodoList;
addTodo
// Input.jsx
const queryClient = useQueryClient();
const mutation = useMutation(addTodo, {
onSuccess: () => {
queryClient.invalidateQueries("todos");
},
});
(...)
const { data } = useQuery("todos", getTodos);
(...)
mutation.mutate(newTodo);
removeTodo, switchTodo
import { useMutation, useQueryClient } from "react-query";
import { removeTodo, switchTodo } from "../../../api/todos";
function Todo({ todo, isActive }) {
const navigate = useNavigate();
const queryClient = useQueryClient();
const removeMutation = useMutation(removeTodo, {
onSuccess: () => {
queryClient.invalidateQueries("todos");
},
});
const switchMutation = useMutation(switchTodo, {
onSuccess: () => {
queryClient.invalidateQueries("todos");
},
});
// 완료, 취소를 handling하는 함수
const handleSwitchButton = () => {
const updatedTodo = {
id: todo.id,
isDone: !todo.isDone,
};
switchMutation.mutate(updatedTodo);
};
// [삭제] 버튼 선택 시 호출되는 함수(user의 confirmation 필요)
const handleRemoveButton = () => {
if (window.confirm(CONFIRM_MESSAGE)) {
removeMutation.mutate(todo.id);
}
};
// [상세보기]를 선택하는 경우 이동하는 함수
const handleDetailPageLinkClick = () => {
navigate(`/${todo.id}`);
};
return (
<StyledDiv>
<FlexTitleBox>
<StyledTitle>{todo.title}</StyledTitle>
<LinkedP onClick={handleDetailPageLinkClick}>[상세보기]</LinkedP>
</FlexTitleBox>
<HeightBox height={10} />
<StyledContents>{todo.contents}</StyledContents>
<HeightBox height={20} />
<FlexButtonBox>
<TodoButton onClick={handleSwitchButton}>
{isActive ? "완료" : "취소"}
</TodoButton>
<TodoButton onClick={handleRemoveButton}>삭제</TodoButton>
</FlexButtonBox>
</StyledDiv>
);
}
export default Todo;
'항해 > TIL' 카테고리의 다른 글
TIL(3/7) / level5 과제 중 에러들 (0) | 2024.03.07 |
---|---|
TIL(3/6) / aws s3 액세스 키 발급 (0) | 2024.03.07 |
TIL(3/2) / CSR, SSR (0) | 2024.03.02 |
TIL(2/29) / lv3 (0) | 2024.02.29 |
TIL(2/28) / React Query (0) | 2024.02.28 |