Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"build-storybook": "storybook build"
},
"dependencies": {
"@tanstack/react-query": "^5.90.16",
"eslint-import-resolver-typescript": "^4.4.4",
"react": "^19.2.0",
"react-dom": "^19.2.0"
Expand All @@ -22,6 +23,7 @@
"@storybook/addon-docs": "^10.1.11",
"@storybook/react-vite": "^10.1.11",
"@svgr/plugin-svgo": "^8.1.0",
"@tanstack/react-query-devtools": "^5.91.2",
"@types/node": "^24.10.1",
"@types/react": "^19.2.5",
"@types/react-dom": "^19.2.3",
Expand All @@ -37,8 +39,8 @@
"eslint-plugin-react-refresh": "^0.4.24",
"eslint-plugin-storybook": "^10.1.11",
"globals": "^16.5.0",
"storybook": "^10.1.11",
"prettier": "3.7.4",
"storybook": "^10.1.11",
"typescript": "~5.9.3",
"typescript-eslint": "^8.46.4",
"vite": "^7.2.4",
Expand Down
38 changes: 38 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion src/app/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
import { createRoot } from "react-dom/client";

import App from "@app/App";
import AppProviders from "@app/providers";

createRoot(document.getElementById("root")!).render(

Check warning on line 7 in src/app/main.tsx

View workflow job for this annotation

GitHub Actions / build-and-deploy

Forbidden non-null assertion
<StrictMode>
<App />
<AppProviders>
<App />
</AppProviders>
</StrictMode>
);
Empty file removed src/app/providers/.gitkeep
Empty file.
26 changes: 26 additions & 0 deletions src/app/providers/QueryProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { PropsWithChildren } from "react";

Check warning on line 1 in src/app/providers/QueryProvider.tsx

View workflow job for this annotation

GitHub Actions / build-and-deploy

`react` type import should occur after import of `@shared/lib/react-query`

Check warning on line 1 in src/app/providers/QueryProvider.tsx

View workflow job for this annotation

GitHub Actions / build-and-deploy

There should be at least one empty line between import groups
import { Suspense, lazy } from "react";

Check warning on line 2 in src/app/providers/QueryProvider.tsx

View workflow job for this annotation

GitHub Actions / build-and-deploy

`react` import should occur after import of `@tanstack/react-query`
import { QueryClientProvider } from "@tanstack/react-query";

import { queryClient } from "@shared/lib/react-query";

const ReactQueryDevtools = import.meta.env.DEV
? lazy(async () => {
const mod = await import("@tanstack/react-query-devtools");
return { default: mod.ReactQueryDevtools };
})
: null;

export default function QueryProvider({ children }: PropsWithChildren) {

Check warning on line 14 in src/app/providers/QueryProvider.tsx

View workflow job for this annotation

GitHub Actions / build-and-deploy

Function component is not an arrow function
return (
<QueryClientProvider client={queryClient}>
{children}

{import.meta.env.DEV && ReactQueryDevtools ? (
<Suspense fallback={null}>
<ReactQueryDevtools initialIsOpen={false} />
</Suspense>
) : null}
</QueryClientProvider>
);
}
7 changes: 7 additions & 0 deletions src/app/providers/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { PropsWithChildren } from "react";

import QueryProvider from "./QueryProvider";

Check warning on line 3 in src/app/providers/index.tsx

View workflow job for this annotation

GitHub Actions / build-and-deploy

`./QueryProvider` import should occur before type import of `react`

export default function AppProviders({ children }: PropsWithChildren) {

Check warning on line 5 in src/app/providers/index.tsx

View workflow job for this annotation

GitHub Actions / build-and-deploy

Function component is not an arrow function
return <QueryProvider>{children}</QueryProvider>;
}
Comment on lines +5 to +7
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저는 query-provider로 바로 App.tsx를 감싸는 구조로 생각했는데, 여러 provider를 합성하는 역할을 수행하는 AppProviders를 별도로 둔 점이 인상깊었어요.
만약 다른 provider가 늘어날 경우, App.tsx가 여러 provider로 감싸지는 약간은 지저분한 구조가 되었을 것 같은데
앱 진입점을 깔끔하게 유지할 수 있는 방향이라 확장성 측면에서 너무 좋은 구조화같습니다❣️

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

index.ts에서 단순히 export만 모아주는 방식이 아닌 AppProviders로 묶어주는 구조를 처음 봐서 조금 찾아보았는데 App.tsx 이 깔끔해지고 추가되는 프로바이더를 해당 파일에서만 추가하면 된다는 점에서 유지보수성이 굉장히 좋은 코드인 거 같습니다~ 하나 배워가욥~!!

Empty file removed src/shared/lib/.gitkeep
Empty file.
1 change: 1 addition & 0 deletions src/shared/lib/react-query/index.ts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

query-client 파일이 이동해서 해당 index.ts 파일도 shared/api 로 옮겨주어야 할 거 같습니다!

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { queryClient } from "./queryClient";
36 changes: 36 additions & 0 deletions src/shared/lib/react-query/queryClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { MutationCache, QueryCache, QueryClient } from "@tanstack/react-query";

export const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: 0,
refetchOnWindowFocus: false,
refetchOnReconnect: true,

staleTime: 30 * 1000,
gcTime: 10 * 60 * 1000,

throwOnError: false,
},
mutations: {
retry: 0,
throwOnError: false,
},
},

queryCache: new QueryCache({
onError: (error: unknown) => {
// TODO: API 초기 세팅 PR merge 후 공통 에러 핸들러 연결
// handleApiError(error);
console.error(error);
},
}),

mutationCache: new MutationCache({
onError: (error: unknown) => {
// TODO: API 초기 세팅 PR merge 후 공통 에러 핸들러 연결
// handleApiError(error);
console.error(error);
},
}),
});
Loading