다른 서버와의 API 통신과 비동기 데이터 관리를 위해 Redux-thunk, Redux-Saga등의 미들웨어를 사용할 수 있었으나, 다음의 문제가 있었다.
하지만 그에 비해 Query는 다음의 장점이 있었다.
어떤 데이터에 대한 요청을 의미한다.
axios의 경우 get요청과 비슷하다.
어떤 데이터의 변경.
어떤 데이터라 함은, 데이터 그룹 그 자체를 의미.
바꾼다는 것은 추가, 수정, 삭제를 위미. CRUD 중, CUD에 해당한다.
axios의 경우 post, put, patch, delete 요청과 비슷하다.
Query를 Invalidation 즉, 무효화 시킨다.
기존에 가져온 Query는 서버 데이터이기 때문에, 언제든지 변경이 생길 수 있다. 그렇기 때문에 '최신 상태가 아닐 수' 있다. 그런 경우, 기존 쿼리를 '무효화' 시킨 후 최신화 해야한다.
그 기능을 하는 것이 Query Invalidation이다.
yarn add react-query
App.jsx)
import React from "react";
import Router from "./shared/Router";
import { QueryClient, QueryClientProvider } from "react-query";
const queryClient = new QueryClient();
const App = () => {
return (
<QueryClientProvider client={queryClient}>
<Router />;
</QueryClientProvider>
);
};
export default App;
QueryClientPrivider : 데이터를 읽어오는 기능(QueryClient)을 애플리케이션 전체에 주입하는 API
useQuery를 이용하여 조회기능을 구현해보자. src > api 폴더를 만들어주고 그 아래에 todos관련 api를 관리할 파일을 만들자.
src > api > todos.js
import axios from "axios";
// 모든 todos를 가져오는 api
const getTodos = async () => {
const response = await axios.get("http://localhost:3000/todos");
return response;
};
export { getTodos };
TodoList 컴포넌트의 코드도 변경
TodoList.jsx)
import React from "react";
import { StyledDiv, StyledTodoListHeader, StyledTodoListBox } from "./styles";
import Todo from "../Todo";
import { __getTodosThunk } from "../../modules/todosSlice";
import { getTodos } from "../../../api/todos";
import { useQuery } from "react-query";
/**
* 컴포넌트 개요 : 메인 > TODOLIST. 할 일의 목록을 가지고 있는 컴포넌트
* 2022.12.16 : 최초 작성
*
* @returns TodoList 컴포넌트
*/
function TodoList({ isActive }) {
const { isLoading, isError, data } = useQuery("todos", getTodos);
if (isLoading) {
return <p>로딩중입니다....!</p>;
}
if (isError) {
return <p>오류가 발생하였습니다...!</p>;
}
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;
useQuery hook에 대해서 다시 한번 알아보자.
import { useQuery } from 'react-query';
import { fetchTodoList } from '../api/fetchTodoList';
function App() {
const info = useQuery('todos', fetchTodoList);
}
1. 첫 번째 인자 'todos' 이걸 쿼리의 키(Query Keys)라고 부른다.
2. 두 번째 인자, 'fetchTodoList' 이걸 쿼리 함수(Query Function)이라고 부른다.
3. useQuery의 결과물
위에서 언급했듯이, query와는 다르게 mutation은 CUD(create, update, delete)에서 사용된다.
ex)
// [출처] : 공식문서
function App() {
const mutation = useMutation(newTodo => {
return axios.post('/todos', newTodo)
})
return (
<div>
{mutation.isLoading ? (
'Adding todo...'
) : (
<>
{mutation.isError ? (
<div>An error occurred: {mutation.error.message}</div>
) : null}
{mutation.isSuccess ? <div>Todo added!</div> : null}
<button
onClick={() => {
mutation.mutate({ id: new Date(), title: 'Do Laundry' })
}}
>
Create Todo
</button>
</>
)}
</div>
)
}
useMutation은 hook이다.