간단한 사이트의 경우 데이터의 수가 많지 않아서 state와 props만으로도 충분히 만들 수 있다.
하지만 대부분의 사이트는 데이터가 많기 때문에 프롭스 드릴링은 발생할 수 밖에 없는데 이러한 상황을 막기 위해 리액트 팀에서는 React-context를 만든다.
데이터를 전역으로 관리하면 프롭스드릴링을 방지할 수 있지만 context의 부족한 점을 보완하기 위해서 redux / recooil 등 다양한 상태관리 라이브러리가 등장.
상태관리를 하는 데이터는 2가지로 나눌 수 있다.
- 클라이언트 상태
- ui의 상태값
- 입력 폼에 입력한 데이터 등
- 서버 상태
- 서버에서 가져오는 데이터를 관리
서버 상태는 데이터는 몇가지 특징을 가지고 있다.
- 비동기식 구현
- 서버에서 데이터를 받아오기까지 시간이 걸리기 때문
- 플레이스홀더를 보여주거나 로딩처리
- 서버에서 데이터를 불러올 때 에러가 났을 경우 에러처리 및 유저 안내 구현 고민
- 최신상태 유지
- 데이터를 한 번 받아오면 끝이 아니라 최신 데이터를 가능한 유지해야한다.
redux, recoil은 보통 클라이언트 상태 데이터를 관리하기 위해 나온 라이브러리,
redux에도 서버 상태 관리가 가능하지만 보일러플레이트가 많기 복잡하기 때문에
서버 상태를 집중적으로 관리하기 위한 라이브러리인 react-query가 나왔다.
1.React-query
리액트 쿼리의 특징이다.
- 데이터 Fetching, Caching, 동기화, 서버 업데이트 등을 쉽게 만들어줌
- Caching을 통해 애플리케이션의 속도를 향상
- 동일한 데이터에 대한 중복 요청 제거
- 실시간 업데이트 및 동기화
- GarbageCollection을 이용하여 서버쪽 데이터 메모리를 관리해줌
- 비동기 과정을 선언적으로 관리할 수 있다.
그 외에 infinite-query, optimistic-Update, usequeryClinet와 같은 옵션들도 많이 제공
npm install @tanstack/react-query
npm 에서 react-query를 설치
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
function App() {
const queryClient = new QueryClient();
return (
<QueryClientProvider client={queryClient}>
<Home />
</QueryClientProvider>
);
}
export default App;
react-query를 사용하려면 쿼리클라이언트를 제공하는 provider를 설정해줘야한다.
App.js파일에 queryClinet를 import해서 queryClient를 만들어준다.
그리고 QueryClientProvider를 통해 App컴포넌트의 자식 컴포넌트에 전달해줘야 자식 컴포넌트에서 react-query를 사용할 수 있다.
react-query 개발자도구
npm install @tanstack/react-query-devtools
react-query를 사용해서 개발하 때 편하게 볼 수 있게 해주는 react-query 개발자 도구도 같이 사용해주자
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
function App() {
const queryClient = new QueryClient();
return (
<QueryClientProvider client={queryClient}>
<Home />
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
);
}
2. useQuery
react-query를 이용해 서버로부터 데이터를 받아오기 위해 useQuery를 사용, (reactHook)
api.js파일을 만들고 getposts라는 함수를 만들어 서버로부터 포스트 목록을 받아오자
api.js
const BASE_URL = "https://------------";
export async function getPosts() {
const response = await fetch(`${BASE_URL}/posts`);
return await response.json();
}
그리고 페이지를 보여주는 home.js 파일에서 getposts를 import 하고 출력값 확인하기
home.js
import React from "react";
import { useQuery } from "@tanstack/react-query";
import { getPosts } from "./api";
const Home = () => {
const data = useQuery({
queryKey: ["getposts"],
queryFn: getPosts,
});
return <div>Home</div>;
};
export default Home;
useQuery와 getposts를 import하고 usQury의 옵션인 queryKey, queryFn 을 설정하면
getposts의 데이터가 잘 불러와지는 것을 볼 수 있고
console.log(data)를 찍어보면 useQuery의 리턴값으로 다양한 상태 정보가 있는 것을 확인할 수 있다.
만약 특정 유저에 대한 데이터만 불로오고 싶을 경우에는 서버로부터 특정 유저의 데이터만 받아오는 api함수를 작성한 다음에
api.js
export async function getPostsUsername(username) {
const response = await fetch(`${BASE_URL}/posts?username=${username}`);
return await response.json();
}
queryKey를 'usenamegetposts'로 지정해주고 두번째로 임의로 지정한 usename을 넣어주면
import React from "react";
import { useQuery } from "@tanstack/react-query";
import { getPosts, getPostsUsername } from "./api";
const Home = () => {
const username = "ddireator";
const { data: postusername } = useQuery({
queryKey: ["usernamegetposts", username],
queryFn: () => getPostsUsername(username),
});
console.log(postusername);
return <div>Home</div>;
};
export default Home;
특정 username에 대한 쿼리만 따로 캐싱이 된 것을 볼 수 있다.
queryKey를 배열로 지정하는 이유는 배열을 활용해 계층적인 쿼리키를 설정하는 것이 가능하고 동적으로 쿼리를 추가할 수 있기 때문이다. 문자열 뿐만 아니라 변수를 넣어 사용 가능함.
'리액트 궁금증' 카테고리의 다른 글
[react-query] 3. react-query의 캐싱 (0) | 2024.06.17 |
---|---|
[react-query] 2. react-query의 status (0) | 2024.06.17 |
react-modal을 사용한 모달 만들기 (0) | 2024.06.02 |
useReducer 다시 찾아볼것 (0) | 2024.02.02 |
React children (0) | 2024.01.18 |