저번에 했던 부분에 이어서 해보겠다.
전에 했었던 것처럼 제출버튼을 누르면 결과값이 나온다. 이 결과물들이 나오는데 문제가 하나 생겼다. 이를 디버깅하는 과정을 그릴 것이다.
useQuery
를 이용해 네트워크 코드를 호출하여 서버 데이터를 관리하지 않는가? 그 전에 이러한 코드를 썼다.
const ChatResponse = ({ prompt }: ChatResponseProps) => {
const { data, isLoading } = useQuery(["chatResponse", prompt], () => getChatResponse(prompt));
return isLoading ? <div>Loading...</div> : <div>{data?.resText}</div>;
};
그런데 개발서버를 열어서 시도해봤는데 값은 잘 나오지만 어째선지 서버 요청을 계속 하고, 계속 값이 리프레쉬 됐다. 왜그런지 useQuery
개념을 조금 보며 살펴보자.
여기서 먼저 알아둬야할게 useQuery
의 개념 중 stale 상태라는 개념이 있다.
직역하면 '오래된'이라는 뜻으로, 리액트쿼리에선 fetch해온 데이터가 어느 기준점에 의해 '오래된' 상태라는 뜻이다.
직역하면 '신선한'이라는 뜻으로, fetch해온 데이터가 어느 기준점으로 보았을 때, 데이터가 아직 '신선한'이라는 뜻이다.
즉, stale한 상태면 useQuery
가 실행되어 refetch가 일어나 fresh한 상태로 된다는 뜻이다. 그러므로 useQuery
에 상황에 맞는 옵션값을 주지 않는다면 이상환 상황이 발생하는 것이다.
다시 돌아와서 내 상황에 대입해보자면
refetchOnMount
)이러한 연유로 나는 적절한 옵션값을 넣어야했다.
옵션이 문제였기에 공식문서를 살펴보았더니 staleTime
이라는 옵션을 가져와 내가 적절하게 설정해야했다. 기본값은 0ms고 setTimeOut
메소드처럼 ms 단위가 기본이다.
내 상황은 유저가 다시 제출 같은 요청이 안일어나면 변수명을 가져오지 않게 하고 싶어서 staleTime
의 시간 자체를 없앴어야했다.
그 값은 바로 infinity
다.
const ChatResponse = ({ prompt }: ChatResponseProps) => {
const { data, isLoading } = useQuery(["chatResponse", prompt], () => getChatResponse(prompt), {
staleTime: Infinity,
});
const result = !isLoading && data ? data.resText : "";
return <div>{result}</div>;
};
아까와의 차이점은 staleTime이다. 저걸 넣었으니 이제 한번만 요청하면 다시 요청 안될 것이다. infinity
를 쓴다면 fresh
상태로 계속 나둬져서 갱신이 되지 않는다.
됐다! 다음번엔 그에 맞게 디자인을 해보자
리액트 쿼리가 서버 데이터관리에 유용하다는건 알았지만 어디서 어떻게 써야하는지 잘몰랐는데 이글보고 도움이되네요 다음에도 쿼리이용한 코드 더보여주세요 ㅎㅎㅎㅎ..