-
[ React ] 쉽고, 직관적인 React QueryTIL 2024. 2. 22. 22:54728x90
다른 서버와의 API 통신과 비동기 데이터 관리를 위해 Redux-thunk, Redux-Saga 등 미들웨어를 채택해서 사용했다.
하지만 Redux-thunk, Redux-Saga 에는 다음과 같은 문제가 존재했는데
1. 보일러 플레이트 : 코드량이 너무 많다.
2. 규격화 문제 : Redux가 비동기 데이터 관리를 위한 전문 라이브러리가 아니다. ( 규격화 문제 )
반면, React Query는 많은 강점을 가지고 있다. ( 쉽고, 책임에서 자유롭다 )
1. 보일러 플레이트를 만들다가 오류가 날 일이 없다.
2. 내가 만든 부분이 아니기에 잘못이 일어난들 내 잘못이 아니다.
3. 사용방법이 기존 Redux-Thunk 대비 너무 쉽고 직관적이다.
✅ 리액트 쿼리의 주요 키워드 3가지
🚩 Query
- 어떤 데이터에 대한 요청을 의미한다.
- axios의 경우 get 요청과 비슷하다.
const response = await axios.get(’http://localhost:3000/todos’)
🚩 Mutation
- 어떤 데이터를 변경하는 것.
- 어떤 데이터라 하면, 데이터 그룹 그 자체를 의미한다.
- 바뀐다는 것은 추가, 수정, 삭제를 의미. CRUD 중 CUD (create, update, delete)에 해당.
- axios의 경우 post, put, patch, delete 요청과 비슷하다.
axios.post(’http://localhost:3000/todos’., newTodo); axios.patch(`http://localhost:3000/todos/${id}`, {isDone: true});
🚩 Query Invalidation
- 위에서 보았던 Query를 invalidation 즉, 무효화 시킨다는 의미이다.
- 무효화? 기존에 가져온 Query는 서버 데이터이기 때문에, 언제든지 변경이 있을 수 있다. 그렇기 때문에 '최신 상태가 아닐 수' 있다는 말이다. 그런 경우, 기존의 쿼리를 무효화 시킨 후 최신화 시켜야한다.
- 이런 과정을 React Query에서는 알아서 해준다. 그 유용한 기능이 바로 Query Invalidation 이다.
🛠️ React Query 설치 명령어
yarn add react-query
App.jsx
import React from "react"; import Router from "./shared/Router"; import { QueryClient, QueryClientProvider } from "react-query"; const queryClient = useQueryClient(); const App = () => { return ( <QueryClientProvider client={queryClient}> <Router />; </QueryClientProvider> ); }; export default App;
- QueryClientProvider : 데이터를 읽어오는 기능(QueryClient)을 애플리케이션 전에 주입하는 API
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"; 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;
- const { isLoading, isError, data } = useQuery( "todos", getTodos );
위 부분이 리액트 쿼리의 가장 큰 장점이라 할 수 있다. Thunk를 사용하면 isLoading, isError를 개발자가 직접 만들어야 했다면, 리액트 쿼리는 서버 데이터를 위한 표준을 제시하고 있기에 개발자에 따라 바뀔 염려가 없다.
return문에 도착하기 전, isLoading/isError 에 따른 별도 처리를 통해 대기처리/오류처리를 쉽게 해결했다.
Input.jsx
... import { addTodo } from "../../../api/todos"; import { QueryClient, useMutation } from "react-query"; ... function Input() { ... const queryClient = new QueryClient(); const mutation = useMutation(addTodo, { onSuccess: () => { // Invalidate and refresh // 이렇게 하면, todos라는 이름으로 만들었던 query를 // invalidate 할 수 있어요. queryClient.invalidateQueries("todos"); }, });
[ invalidation 과정 ]
- Input.jsx 에서 값 입력으로 인해 서버 데이터가 변경됨
- onSuccess가 일어나면 기존의 Query인 "todos"는 무효화
- 새로운 데이터를 가져와서 "todos"를 최신화
- TodoList.jsx를 갱신한다.
따라서 리액트 앱은 최신 상태의 서버 데이터를 유지할 수 있게 된다.
728x90'TIL' 카테고리의 다른 글
[ React ] 공통된 로직, 기능을 깔끔하게! " Custom Hooks " (0) 2024.02.28 [ React ] 과도한 이벤트 핸들러 호출 방지 throttling & debouncing (0) 2024.02.23 [ React ] 리덕스 미들웨어 - Redux Thunk (1) 2024.02.20 [ React ] axios , json-server 를 이용한 통신 실습 (0) 2024.02.19 [ React ] 빠른 Frontend 개발을 위한 툴, Vite ! (0) 2024.02.16