기존 상태 라이브러리는 비동기 및 서버 상태 관리에 적합하지 않다
우리는 서버 상태를 관리하기 위한 가장 좋은 라이브러리다!!
구 리액트 쿼리
현 탠스택 쿼리
서버 상태 관리란?
클라이언트에서 제어하지 않은 상태에서 관리됨
비동기 api 필요
사용자가 모르는 사이에 바뀔 수도 있음
캐싱
같은 데이터 요청 중복 제거
최대한 빠르게 업데이트 반영
stale-while-revaildate
http 캐싱에도 사용되는 캐싱 매커니즘
-> 캐싱된 데이터를 사용자에게 줌 + 비동기적으로 콘텐츠를 서버에서 revaildate
fetching
이건 fresh한 상태임
조건에 따라 (staleTime) stale로 바뀜
사용되지 않으면 inactive 로 바뀜
gcTime(cacheTime) 가비지 콜렉터 타임... 캐시를 제거하는 거임
QueryClient
모든 쿼리에 대한 상태/캐시를 가지고 있는 클래스임
QueryClient 인스턴스를 생성하여 쿼리 기능을 사용함
const queryClient = new QueryClient({
defaultOption : {
queries : {
staleTime : 1000 * 60,
retry: 1
},
mutations : {
retry: 1
}
}
})
<QueryClientProvier client={queryClient}>
.............
서버에서 데이터를 받아올 때 사용하는 기능
v5라서 ({}) 객체 형체로 바뀜
const query = useQuery({
queryKey: ["todo"],
queryFn : fetchTodo
})

enable : false , 쿼리 자동으로 실행여부
retry: 실패시 몇 번? 기본은 3번임
select : res에서 필요한 값만 추출
refetchInterval: 주기적으로 얼마나 부를 건지
throwOnError: error boundary로 에러를 전파할지 여부
data: resolved 된 데이터
isLoading : 최초 패치가 in-flight 상태 (캐시 있거나 없음)
=> 처음 패칭했을 때 뜨는 거. 이후에 캐싱된 거 가져올 때는 작동 안 함
isFetching : fetch가 실행될 때마다 true (캐시 있음)
=> 캐싱 상관없이 모두 뜸
였는데
v5는 바뀌었다함
- 처음 데이터를 가져올 때는 isLoading과 isPending이 모두 true
- 캐싱된 데이터를 가져올 때는 isLoading만 true가 되고, isPending은 false 상태를 유지
둘이 바뀐듯...
useQueries
const queries = useQueries([
{ queryKey: ['user'], queryFn: fetchUser },
{ queryKey: ['posts'], queryFn: fetchPosts },
]);
const queries = useQueries({
queries: [
{ queryKey: ['user'], queryFn: fetchUser },
{ queryKey: ['posts'], queryFn: fetchPosts },
],
});
const { data, isLoading } = useQuery(['user'], fetchUser, {
placeholderData: {
name: 'Loading...',
age: null,
},
});
placeholderData : 데이터 가져오기 전에 목데이터
useQuery를 여러개 부를 때
useQueries를 사용하면
const queries = useQueries([
{ queryKey: ['user'], queryFn: fetchUser },
{ queryKey: ['posts'], queryFn: fetchPosts },
]);
const userQuery = queries[0];
const postsQuery = queries[1];
if (userQuery.isLoading || postsQuery.isLoading) return <div>Loading...</div>;
if (userQuery.error || postsQuery.error) return <div>Error: {userQuery.error?.message || postsQuery.error?.message}</div>;
이렇게 병렬적으로 가져오기도하면서
각각 error 처리가 가능함
- 독립적인 상태 관리가 필요할 때: useQueries를 사용하는 것이 더 나음
- 간단하게 여러 데이터를 한 번에 가져올 때: Promise.all을 사용하여 한 쿼리 내에서 처리
Mutations
URD 에 사용되는 기능 (CRUD)
const query = useMutation({
queryFn: fetchTodo
})


onMutation : mutate 함수가 실행되기 전에 실행되는 함수
(optimistic update)
mutate : mutation 함수를 실행시키는 함수
onSettled : 실패했든 성공했든 상관없이 호출
queryClient.invalidateQueries({
........
})
이건 todo 만들어 놓고 다시 쿼리 키를 이용해 데이터를 부르려는 거임
업데이트 쳤으니까 새로운 거 받아와야 함
useInfiniteQuery


isFetchingNextPage가 page +1 인 듯
신박한 거....

캐싱된 데이터를 가져와서 다른 거 패칭하기 전에 미리 보여줄 수도 있음
낙관적 업데이트
1. variables


2. onMutate를 통한 낙관적 업데이트
const mutation = useMutation(updateUser, {
onMutate: async (newData) => {
// 기존 쿼리 데이터 취소
await queryClient.cancelQueries(['user']);
// 스냅샷으로 이전 값 가져오기
const previousUserData = queryClient.getQueryData(['user']);
// 낙관적 업데이트 수행
queryClient.setQueryData(['user'], (old) => ({
...old,
...newData,
}));
// 오류 발생 시 롤백을 위해 스냅샷 반환
return { previousUserData };
},
onError: (err, newData, context) => {
// 오류 발생 시 롤백
queryClient.setQueryData(['user'], context.previousUserData);
},
onSettled: () => {
// 변이 완료 후 데이터 다시 가져오기
queryClient.invalidateQueries(['user']);
},
});
const handleUpdate = () => {
mutation.mutate({ name: 'New Name' });
};
variables 와 onMutate 의 낙관적 업데이트 차이
variables은 예시와 같이 업데이트가 진행중인걸 알려주려고 만든 거임
onMutate의 낙관적 업데이트는 말 그대로 낙관적으로 판단하고 빠르게 UI를 보여주는 거임
이거 두개는 같이 못 쓸 거 같은데
왜 두개 다 함께 쓰라고 권장하는 건지 모르겠음
setQueryData
queryClient.setQueryData(queryKey, updater);
queryKey: 업데이트할 쿼리의 키.
updater: 새로운 데이터 또는 기존 데이터를 업데이트하는 함수.
캐시된 데이터 가져오면서 바꾸는 거임
위에 onMutate 처럼
useSuspenseQuery
데이터를 불러오는 동안 fallback UI를 대신 보여주는 기능
useQuery에 suspense: true 옵션 넣은 거랑 똑같음
const query = useSuspenseQuery({
..........
})
suspense로 감싼 컴포넌트에서 useQuery suspense : true 설정 안하고 그냥 쓰면
suspense fallback 기능을 못 쓴다고 함....
글쿤

보통 폴더명 이렇게 짓는 듯
===============================
로딩 상태 관리
낙관적 업데이트
캐싱 기능
때문에 많이 썼던 듯
이제야 이해가 갔다
contextAPI를 사용하긴 했는데 (키를 이용해서 관리하니까 필요했던 듯, 캐싱도 그렇고)
서버 상태(fetch 데이터) // 클라이언트 상태 를 분리해서 봐야하는 듯
단순 서버 상태를 위한 라이브러리였음
참고
https://www.youtube.com/shorts/-RsCv5uZziI
'TIL' 카테고리의 다른 글
클로저 - hof - 리액트 - hoc - class (0) | 2024.08.04 |
---|---|
es5은 어떻게 브라우저에서 동작했을까 & UMD (0) | 2024.07.28 |
타입스크립트 never, 컨디셔널 타입 (0) | 2024.07.27 |
jest 2 테스트 종류 (1) | 2024.07.21 |
타입스크립트의 추론 (1) | 2024.07.20 |
댓글