인프런 커뮤니티 질문&답변

bj2525님의 프로필 이미지
bj2525

작성한 질문수

풀스택 리액트 라이브코딩 - 간단한 쇼핑몰 만들기

상품목록 페이지 만들기

getQueryClient

작성

·

603

0

안녕하세요 재남님! getQueryClient 질문과 error 관련해서 질문 드립니다!

export const getClient = (() => {
  let client: QueryClient | null = null;

  return () => {
    if (!client) {
      client = new QueryClient();
      return client;
    }
  };
})();

getClient 함수 안에 client라는 변수를 선언하고 client가 없을시에만 new QueryClient()를 만들어주고 값을 반환한다 라고 이해했는데, 로직 중간에 return ( ) => {.....}이 해주는 역활이 정확이 무엇인지 궁금하고, getClient를 왜 즉시실행 함수로 작성하신건지 궁금합니다! (즉시실행을 하지않아도 다른 컴포넌트에서 useEffect안에 함수를 호출하면 되지않을까 하는 생각에 질문드렸어요!)

마지막으로 client type 지정 하실 때

new QueryClient(config?: QueryClientConfig | undefined): QueryClient 라고 되어있는 부분에서 QueryClient가 있어서 적어주신걸로 봤는데, new QueryClient의 반환 type이 QueryClient 라서 type지정을 해주신건지 궁금합니다!

Error

queryClient 만들고 실행하니 아래와 같은 error가 발생했습니다.

문제

렌더링이 되지 않고 Router 기능도 되지 않음

구글링 하고 적용해보았던 것

1. react-query 버전을 v4에서 다운그레이드 하였음

  1. react와 react-dom 버전 다운그레이드 하였음

  1. FunctionComponent 관련해서 react type(?)이 바뀐 부분이 있어서 https://github.com/TanStack/query/issues/3476 참조해서 index.t.ds 파일에 해당 내용 넣어주고 실행하였음

결론

1,2,3을 적용해도 아직 에러를 고치지 못했습니다..ㅜㅜ

 

스크린샷 2022-09-07 오후 8.41.50.png스크린샷 2022-09-07 오후 8.43.35.png

package.json

{
  "name": "shopping-mall",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-query": "^3.34.16",
    "react-router-dom": "^6.3.0",
    "vite-plugin-next-react-router": "^0.6.2"
  },
  "devDependencies": {
    "@types/react": "^17.0.33",
    "@types/react-dom": "^17.0.10",
    "@vitejs/plugin-react": "^2.1.0",
    "typescript": "^4.6.4",
    "vite": "^3.0.0"
  }
}

App.tsx

import { QueryClientProvider } from "react-query";
import { useRoutes } from "react-router-dom";
import { getClient } from "./queryClient";
import { routes } from "./routes";
import { ReactQueryDevtools } from "react-query/devtools";

const App = () => {
  const element = useRoutes(routes);
  const queryClient = getClient();

  return (
    <QueryClientProvider client={queryClient}>
      {element}
      <ReactQueryDevtools initialIsOpen={false} />
    </QueryClientProvider>
  );
};

export default App;

답변 1

1

정재남님의 프로필 이미지
정재남
지식공유자

코드가 잘못되었습니다. 아래처럼 return client를 한 줄 내려주세요.

...
  return () => {
    if (!client) {
      client = new QueryClient();
    }
    return client;
  };
})();

이렇게 하면 client에 마우스를 올렸을 때 타입이 QueryClient | undefined가 아니라 QueryClient만 나오게 될겁니다.

getClient 함수 안에 client라는 변수를 선언하고 client가 없을시에만 new QueryClient()를 만들어주고 값을 반환한다 라고 이해했는데, 로직 중간에 return ( ) => {.....}이 해주는 역활이 정확이 무엇인지 궁금하고, getClient를 왜 즉시실행 함수로 작성하신건지 궁금합니다! (즉시실행을 하지않아도 다른 컴포넌트에서 useEffect안에 함수를 호출하면 되지않을까 하는 생각에 질문드렸어요!)

 

이 부분은 사실 이 프로젝트에서는 꼭 필요한 부분은 아닙니다. useEffect에서 사용할 건 아니고, QueryClientProvider에 client를 전달하는 최상단 컴포넌트의 외부에서 한 번만 인스턴스화 하면 되긴 해요. 제 코드는 과거 실무에서 겪었던 이슈에서 비롯되었습니다.

next.js와 연관이 있는데, 당시 저희팀 프로젝트 코드상에 어떤 문제가 있어서 그랬는지 정확히 기억나지 않지만, 아무튼 페이지 전환시 QueryClient의 캐시가 날라가고 새롭게 초기화되었습니다. 즉 페이지마다 매 번 client = new QueryClient()가 실행되어, 기존에 불러온 서버데이터를 다시 요청하게 되는 요상한 상황이었어요. 하여 이미 만들어둔 QueryClient가 있다면 페이지 전환시에도 그걸 그대로 사용하도록 할 필요가 있었고, 그 결과가 위의 코드입니다. 그런데 아마 이제는 next.js에서도 이렇게 작성하지 않아도 괜찮지 않을까 싶긴 해요.

즉 과거 업무에서 겪었던 문제상황을 해결하기 위한 코드를 습관적으로 사용한 것일 뿐 필수는 아니고, 이렇게 사용하지 않는 것이 나을 수도 있습니다.

처음 말씀드린 코드 수정을 하시면 다운그레이드하지 않아도 괜찮을거예요.

bj2525님의 프로필 이미지
bj2525
질문자

친절한 설명 감사드려요!

bj2525님의 프로필 이미지
bj2525

작성한 질문수

질문하기