Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(web): Tanstack Query 세팅 및 API 공통 메서드 작성 #57

Merged
merged 4 commits into from
Jul 14, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 0 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
"editor.codeActionsOnSave": {
"source.fixAll": "explicit",
"source.fixAll.eslint": "explicit",
"source.organizeImports": "explicit",
"source.addMissingImports": "explicit"
}
}
5 changes: 4 additions & 1 deletion apps/web/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Providers } from '@sambad/web-domains/commmon';
import { Inter } from 'next/font/google';

import type { Metadata } from 'next';
Expand All @@ -18,7 +19,9 @@ export default function RootLayout({
}>) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
<body className={inter.className}>
<Providers>{children}</Providers>
</body>
</html>
);
}
17 changes: 1 addition & 16 deletions apps/web/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,3 @@
'use client';

import { FirstDomainExampleScreen } from '@sambad/web-domains/first-domain';
import { useEffect } from 'react';

import styles from './page.module.css';

export default function Home() {
useEffect(() => {
console.log('test-main');
}, []);

return (
<main className={styles.main}>
<FirstDomainExampleScreen />
</main>
);
}
export default FirstDomainExampleScreen;
8 changes: 8 additions & 0 deletions apps/web/next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
async rewrites() {
return [
{
source: '/api/:path*',
destination: 'http://ec2-43-203-195-123.ap-northeast-2.compute.amazonaws.com:8080/:path*', // Proxy to Backend
Andrevile marked this conversation as resolved.
Show resolved Hide resolved
},
];
},
compiler: {
emotion: true,
},
Expand Down
5 changes: 3 additions & 2 deletions packages/core/eslint-config/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ module.exports = {
},
],
'no-duplicate-imports': 'error',
'no-unused-vars': ['error', { varsIgnorePattern: '^_', argsIgnorePattern: '^_' }],
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': 'error',
'react/jsx-curly-brace-presence': ['error', { props: 'never', children: 'never' }],
'@typescript-eslint/consistent-type-imports': 'error',

Andrevile marked this conversation as resolved.
Show resolved Hide resolved
'react/no-unknown-property': ['error', { ignore: ['css'] }],
},
overrides: [{ files: ['*.js?(x)', '*.ts?(x)'] }],
Expand Down
1 change: 1 addition & 0 deletions packages/core/eslint-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^7.1.0",
"@typescript-eslint/parser": "^7.1.0",
"@tanstack/eslint-plugin-query": "^5.50.1",
"@vercel/style-guide": "^5.2.0",
"eslint-config-prettier": "^9.1.0",
"eslint-config-turbo": "^2.0.0",
Expand Down
8 changes: 7 additions & 1 deletion packages/core/eslint-config/react-internal.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ const base_eslint_config = require('./base.js');
/** @type {import("eslint").Linter.Config} */
module.exports = {
...base_eslint_config,
extends: ['eslint:recommended', 'plugin:react/recommended', 'prettier', 'turbo'],
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:@tanstack/eslint-plugin-query/recommended',
'prettier',
'turbo',
],
env: {
browser: true,
},
Expand Down
9 changes: 7 additions & 2 deletions packages/web-domains/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@
"private": true,
"exports": {
"./first-domain": "./src/first-domain/index.ts",
"./second-domain": "./src/second-domain/index.ts"
"./second-domain": "./src/second-domain/index.ts",
"./commmon": "./src/common/index.ts"
},
"scripts": {
"lint": "eslint . --max-warnings 0",
"type-check": "tsc --noEmit"
},
"dependencies": {},
"dependencies": {
"@tanstack/react-query": "^5.50.1",
"axios": "^1.7.2"
},
"devDependencies": {
"@sambad/sds": "workspace:*",
"@sambad/eslint-config": "workspace:*",
Expand All @@ -19,6 +23,7 @@
"@types/eslint": "^8.56.5",
"@types/react": "^18.2.61",
"@types/react-dom": "^18.2.19",
"@types/qs": "^6.9.15",
"eslint": "^8.57.0",
"react": "^18",
"typescript": "^5.3.3"
Expand Down
Empty file.
28 changes: 28 additions & 0 deletions packages/web-domains/src/common/apis/base.api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import axios from 'axios';
const baseURL = `/api`;

const axiosInstance = axios.create({
baseURL: baseURL,
});

export class Http {
static async GET<Response = unknown>(...args: Parameters<typeof axiosInstance.get>) {
const response = await axiosInstance.get<Response>(...args);
return response.data;
}

static async POST<Request = unknown, Response = unknown>(...args: Parameters<typeof axiosInstance.post>) {
const response = await axiosInstance.post<Request, Response>(...args);
return response;
}

static async PUT<Request = unknown, Response = unknown>(...args: Parameters<typeof axiosInstance.put>) {
const response = await axiosInstance.put<Request, Response>(...args);
return response;
}

static async DELETE<Response = unknown>(...args: Parameters<typeof axiosInstance.delete>) {
const response = await axiosInstance.delete<Response>(...args);
return response.data;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { QueryClient, useQuery } from '@tanstack/react-query';

import { Http } from '../base.api';

const ping = () => Http.GET<any>('/actuator/health');

export const useHealthCheckQuery = () => {
const { data } = useQuery({
queryKey: ['health'],
queryFn: ping,
});

return { data };
};

export const useHealthCheckPrefetchQuery = async () => {
const queryClient = new QueryClient();

const prefetchedData = await queryClient.prefetchQuery({
queryKey: ['health'],
queryFn: ping,
});

return {
queryClient,
prefetchedData,
};
};
9 changes: 9 additions & 0 deletions packages/web-domains/src/common/contexts/Providers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use client';

import { PropsWithChildren } from 'react';

import { QueryClientProvider } from './QueryClientProvider';

export const Providers = ({ children }: PropsWithChildren) => {
return <QueryClientProvider>{children}</QueryClientProvider>;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use client';
import { isServer, QueryClient, QueryClientProvider as TanstackProvider } from '@tanstack/react-query';
import { PropsWithChildren } from 'react';

const makeQueryClient = () => {
return new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 1000,
refetchOnWindowFocus: false,
retry: 1,
},
},
});
};

let browserQueryClient: QueryClient | undefined = undefined;

const getQueryClient = () => {
if (isServer) {
return makeQueryClient();
}

if (!browserQueryClient) {
browserQueryClient = makeQueryClient();
}
return browserQueryClient;
};

export const QueryClientProvider = ({ children }: PropsWithChildren) => {
const queryClient = getQueryClient();

return <TanstackProvider client={queryClient}>{children}</TanstackProvider>;
};
2 changes: 2 additions & 0 deletions packages/web-domains/src/common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { QueryClientProvider } from './contexts/QueryClientProvider';
export { Providers } from './contexts/Providers';
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { FirstFeatureOfFirstDomainTestButton } from '../components/FirstFeatureO
import { useFirstFeatureOfFirstDomainService } from '../services/useFirstFeatureOfFirstDomainTestService';

export const FirstFeatureOfFirstDomainTestContainer = () => {
const { displayText, handleChangeDisplayText } = useFirstFeatureOfFirstDomainService();
const { displayText, handleChangeDisplayText, data } = useFirstFeatureOfFirstDomainService();

return (
<FirstFeatureOfFirstDomainBox displayText={displayText} onClick={handleChangeDisplayText}>
Expand All @@ -14,6 +14,7 @@ export const FirstFeatureOfFirstDomainTestContainer = () => {
alert('Button is Clicked at Container');
}}
/>
<div css={{ width: '200px', height: '200px', backgroundColor: 'red' }}>{data}</div>
</FirstFeatureOfFirstDomainBox>
);
};
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import { useState } from 'react';

import { useHealthCheckQuery } from '../../../common/apis/queries/useHealthCheckQuery';

export const useFirstFeatureOfFirstDomainService = () => {
const [displayText, setDisplayText] = useState<string>('');

const { data } = useHealthCheckQuery();

const handleChangeDisplayText = () => {
setDisplayText('Test Container Button Clicked');
};

return {
data,
displayText,
handleChangeDisplayText,
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { HydrationBoundary, dehydrate } from '@tanstack/react-query';

import { useHealthCheckPrefetchQuery } from '../../common/apis/queries/useHealthCheckQuery';
import { FirstFeatureOfFirstDomainTestContainer } from '../features/containers/FirstFeatureOfFirstDomainTestContainer';

export const FirstDomainExampleScreen = () => {
export const FirstDomainExampleScreen = async () => {
const { queryClient } = await useHealthCheckPrefetchQuery();
return (
<div>
<h1>도메인 화면을 전체 담당 하는 컴포넌트입니다.</h1>
<FirstFeatureOfFirstDomainTestContainer />
</div>
<HydrationBoundary state={dehydrate(queryClient)}>
<div>
<h1>도메인 화면을 전체 담당 하는 컴포넌트입니다.</h1>
<FirstFeatureOfFirstDomainTestContainer />
</div>
</HydrationBoundary>
);
};
Loading