|
1 | 1 | import type { Preview } from '@storybook/react-vite'; |
2 | 2 | import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; |
3 | 3 | import { initialize, mswLoader } from 'msw-storybook-addon'; |
| 4 | +import { type ReactNode, useState } from 'react'; |
4 | 5 | import { MemoryRouter } from 'react-router'; |
| 6 | + |
| 7 | +import { useAuthQuery } from '../src/feature/auth/application/auth-query'; |
5 | 8 | import { implAuthUsecase } from '../src/feature/auth/usecase/auth-usecase'; |
| 9 | +import { QueryContext } from '../src/feature/shared/context/query-context'; |
| 10 | +import { TokenContext } from '../src/feature/shared/context/token-context'; |
6 | 11 | import { UsecaseContext } from '../src/feature/shared/context/usecase-context'; |
7 | 12 | import { externalCall, implApi } from '../src/infrastructure/api'; |
| 13 | +import { implTokenRepository } from '../src/infrastructure/token/token-repository'; |
8 | 14 | import { handlers } from '../src/mocks/handlers'; |
9 | 15 | import '../src/index.css'; |
10 | 16 |
|
11 | 17 | initialize({ onUnhandledRequest: 'bypass' }); |
12 | 18 |
|
| 19 | +/** |
| 20 | + * QueryClientProvider 안에서 렌더되는 내부 컴포넌트. |
| 21 | + * module 레벨에 정의해야 story 전환 시 불필요한 remount를 방지할 수 있다. |
| 22 | + */ |
| 23 | +const StoryAuthProviders = ({ children }: { children: ReactNode }) => { |
| 24 | + const [token, setToken] = useState<string | null>(null); |
| 25 | + const api = implApi({ externalCall }); |
| 26 | + const tokenRepository = implTokenRepository({ setToken }); |
| 27 | + const authUsecase = implAuthUsecase({ api, tokenRepository }); |
| 28 | + const authQuery = useAuthQuery({ authUsecase }); |
| 29 | + |
| 30 | + return ( |
| 31 | + <QueryContext.Provider value={{ authQuery }}> |
| 32 | + <TokenContext.Provider value={{ token }}> |
| 33 | + <UsecaseContext.Provider value={{ authUsecase }}> |
| 34 | + {children} |
| 35 | + </UsecaseContext.Provider> |
| 36 | + </TokenContext.Provider> |
| 37 | + </QueryContext.Provider> |
| 38 | + ); |
| 39 | +}; |
| 40 | + |
13 | 41 | const preview: Preview = { |
14 | 42 | parameters: { |
15 | 43 | msw: { handlers }, |
16 | 44 | }, |
17 | 45 | loaders: [mswLoader], |
18 | 46 | decorators: [ |
19 | 47 | (Story) => { |
20 | | - const queryClient = new QueryClient({ |
21 | | - defaultOptions: { |
22 | | - queries: { refetchOnWindowFocus: false, retry: false }, |
23 | | - mutations: { retry: false }, |
24 | | - }, |
25 | | - }); |
26 | | - const api = implApi({ externalCall }); |
27 | | - const authUsecase = implAuthUsecase({ api }); |
| 48 | + const [queryClient] = useState( |
| 49 | + () => |
| 50 | + new QueryClient({ |
| 51 | + defaultOptions: { |
| 52 | + queries: { refetchOnWindowFocus: false, retry: false }, |
| 53 | + mutations: { retry: false }, |
| 54 | + }, |
| 55 | + }) |
| 56 | + ); |
28 | 57 |
|
29 | 58 | return ( |
30 | 59 | <MemoryRouter> |
31 | 60 | <QueryClientProvider client={queryClient}> |
32 | | - <UsecaseContext.Provider value={{ authUsecase }}> |
| 61 | + <StoryAuthProviders> |
33 | 62 | <Story /> |
34 | | - </UsecaseContext.Provider> |
| 63 | + </StoryAuthProviders> |
35 | 64 | </QueryClientProvider> |
36 | 65 | </MemoryRouter> |
37 | 66 | ); |
|
0 commit comments