리액트 쿼리(React Query)는 리액트 애플리케이션 데이터 관리를 위한 상태 관리 라이브러리입니다. 리애트 쿼리는 API 호출, 상태 캐싱, 데이터 업데이트 및 동기화, 오류처리 등을 처리하는 간편하고 직관적인 방식을 제공합니다.
어떤 데이터에 대한 요청을 의미.
어떤 데이터를 변경 (추가, 수정, 삭제)
Query를 invalidation. 즉, 무효화 시킨다는 의미.
무효화 시킨다는 것은?
기존에 가져온 Query는 서버 데이터이기 때문에, 언제든지 변경이 있을 수 있음.
그렇기 때문에 '최신 상태가 아닐 수'있다.
→ 기존의 쿼리를 무효화 시킨 후 최신화 시켜야 함.
react-query 설치
yarn add react-query
QueryClientProvider : 데이터를 읽어오는 기능(QueryClient)을 애플리케이션 전체에 주입하도록 하는 API
// 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;
// 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.jsx
import React from "react";
import { getTodos } from "../../../api/todos";
import { useQuery } from "react-query";
function TodoList({ isActive }){
// useQuery(Querykey, 비동기 함수)
const { isLoading, isError, data } = useQuery("todos", getTodos);
if (isLoading) {
return <p>로딩중입니다</p>;
}
if (isError) {
return <p>오류가 발생하였습니다</p>;
}
return (
.
.
.
)
}
useQuery의 인자에 대해
첫 번째 인자 - Query Keys
두 번째 인자 - 쿼리 함수
useQuery의 결과물 - 객체
true
가 된다.true
가 된다.false
가 된다.true
가 된다.false
가 된다.// src > api > todos.js
import axios from "axios"
// .env를 활용하는게 더 바람직 함
const SERVER_URI = "http://localhost:4000";
const getTodos = async () => {
const response = await axios.get(`${SERVER_URI}/todos`);
return response.data
};
const addTodo = async (newTodo) => {
await axios.post(`${SERVER_URI}/todos`, newTodo);
}
export {getTodos, addTodo};
// 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");
},
});
}
invalidate의 과정
Input.jsx에서 값 입력으로 인해 서버 데이터가 변경됨
→ onSuccess가 일어나면 기존의 Query인 "todos"는 무효화
→ 새로운 데이터를 가져와서 "todos"를 최신화시킴
→ TodoList.jsx를 갱신함
따라서 계속해서 리액트 앱은 최신 상태의 서버 데이터를 유지할 수 있게 된다.
무효화라는 뜻이 이해되지 않아서 chatGPT에게 물어본 결과
캐시된 데이터를 무효화(invalidate)시키면, 다음에 해당 데이터를 요청할 때 라이브러리는 새로운 데이터를 가져오게 됩니다. 이것은 캐시된 데이터를 사용하지 않고 서버로부터 새로운 데이터를 다시 요청하는 효과를 가지게 됩니다. 캐시된 데이터를 가져오지 않고 새로운 데이터를 강제로 다시 가져올 수 있습니다.
mutations
query와는 다르게 mutation은 CUD에서 사용된다.
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>
)
}
mutation.mutate(인자)
결과를 객체(object) 형태로 갖고 있다.
그 결과물 객체는 항상 아래 상태 중 하나에 속한다.