문제 발생
nextjs에서 sever mutate를 이용하려면 useRouter()를 사용하여 페이지를 refresh를 해줘야된다.
근데 나는 react-query와 같이 사용중이었는데 문제가 발생했다.
useRouter().refresh()를 하면 react-query의 캐시 데이터가 모두 사라졌다.
아래 사진을 잘 보면 button 클릭시 데이터들이 모두 지워짐
아래는 코드이다.
'use client';
import { useQuery } from '@tanstack/react-query';
import { useRouter } from 'next/navigation';
async function fetchTest() {
return fetch('/api/t', { method: 'get' }).then((res) => res.json());
}
export default function Test() {
const router = useRouter();
const { data } = useQuery(['test'], () => fetchTest());
const onClick = async () => {
router.refresh();
};
console.log('data', data, 123);
return (
<div>
<button className='text-neutral-200 text-xl' onClick={onClick}>
button
</button>
<p className='text-neutral-100 text-xl'>{JSON.stringify(data)}</p>
</div>
);
}
문제 해결
이 문제를 처음 발견했을때 하루를 날려버렸었다;;
원인은 QueryClient를 useState로 감싸주지 않았기 때문
아래 코드를 보면 useState로 QueryClient를 감싸주어서 해결했다.
'use client';
import {
QueryClient,
QueryClientConfig,
QueryClientProvider,
} from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { ReactNode, useState } from 'react';
export default function ReactQueryContext({
children,
}: {
children: ReactNode;
}) {
const options: QueryClientConfig = {
defaultOptions: {
queries: {
staleTime: 4000,
refetchOnMount: true,
},
},
};
const [client, setClient] = useState(new QueryClient(options));
// if state is not used is not to work query-cache
//const client = new QueryClient(options);
return (
<QueryClientProvider client={client}>
{children}
<ReactQueryDevtools />
</QueryClientProvider>
);
}
링크
아래는 해당 코드 테스트 깃허브 샘플파일 내가 만듬 👍
https://github.com/SeungYn/react-query-test
아래는 codesandbox에 만든 샘플인데 useState로 감싼것과 감싸지 않는 코드를 직접 몸으로 느낄수 있게 올려두었다.
잘 작동하는 버전
캐시 사라지는 버전
이유
그럼 이 문제에 대한 이유가 뭐였을까? 그리고 페이지를 refresh를 하는데 왜 캐시 데이터가 유지되는 걸까?
일단 리프레시를 해도 데이터가 유지되는 이유는 nextjs에 나와있었다
한마디로 refresh를 해주면 클라이언트의 상태 데이터 손실 없이 서버에 요청을 하고 최신 데이터로 업데이트를 해주는 것이다.
https://nextjs.org/docs/app/api-reference/functions/use-router
이러한 이유 때문에 QueryClient를 useState에 저장해 두면 refresh를 해도 캐시가 남아있는 것이다. 하지만 F5로 하면 지워짐
그리고 react-query 만든사람(?)의 블로그에서 QueryClient를 사용하려면 useState를 사용해서 안정적이게 사용하라고 글까지 써놨었다. 이유는 어떠한 이유로 앱이 re-render가 되면 캐시가 다날라간다고 한다.
https://tkdodo.eu/blog/react-query-fa-qs#2-the-queryclient-is-not-stable
이거 처음 당했을 때 킹받았었는데 지나고 보면 별게 아니네
'프론트엔드 > NextJS' 카테고리의 다른 글
[NextJS] e2e - PlayWright 설치 및 메인화면 띄우기(1) (1) | 2024.02.06 |
---|---|
Page Caching [Full Route Cache, Router Cache ] (1) | 2024.01.29 |
나도 오픈소스 기여를 ?!?! (with react-query) (0) | 2023.07.15 |
서버 컴포넌트로 데이터 불러오기 (0) | 2023.04.25 |
[실전에서 바로쓰는 NextJS] 렌더링 전략 (2) | 2023.03.14 |