-
Notifications
You must be signed in to change notification settings - Fork 1
Directory Structure
BangDori edited this page May 18, 2024
·
9 revisions
📦src
┣ 📂app/
┣ 📂providers/
┣ 📂routers/
┗ 📜index.tsx
┣ 📂pages/
┣ 📂widgets/
┣ 📂features/
┣ 📂entities/
┗ 📂shared/
┣ 📂axios/
┣ 📂styles/
┣ 📂ui/
┗ 📂util/
애플리케이션 로직이 초기화되는 곳입니다. 프로바이더, 라우터, 전역 스타일, 전역 타입 선언 등이 여기에서 정의됩니다. 애플리케이션의 진입점 역할을 합니다.
-
providers:
RouterProvider
,QueryClientProvider
와 같은 프로바이더들이 위치하는 디렉터리입니다.
// app/providers/query-client.ts
import {
MutationCache,
QueryCache,
QueryClient,
QueryClientConfig,
} from "@tanstack/react-query";
export const queryClientOptions: QueryClientConfig = {
defaultOptions: {},
queryCache: new QueryCache({}),
mutationCache: new MutationCache({}),
};
export const queryClient = new QueryClient(queryClientOptions);
- routers: React Router에 의해 렌더링되는 페이지의 라우터가 정의됩니다.
// app/routers/index.tsx
import { createBrowserRouter, RouteObject } from "react-router-dom";
import RootLayout from "@pages/RootLayout";
import ErrorLayout from "@pages/ErrorLayout";
const routes: RouteObject[] = [
{
path: "/",
element: <RootLayout />,
errorElement: <ErrorLayout />,
},
];
const router = createBrowserRouter(routes);
export default router;
- index.tsx: 애플리케이션의 진입점 역할을 합니다.
페이지에 해당하는 컴포넌트가 여기에서 정의됩니다. 페이지 진입시 데이터를 가져오는 커스텀 훅도 여기에서 정의합니다.
// pages/feeds/FeedsPage.tsx
import { useGetFeeds } from "./useFeeds";
const FeedsPage = () => {
const { feeds } = useFeeds();
return <Feeds feeds={feeds} />;
};
export default FeedsPage;
// pages/feeds/useFeeds.tsx
async function getFeeds(): Promise<Feed[]> {
const { data } = await axiosInstance.get("/feeds");
return data;
}
export function useGetFeeds(): Feed[] {
const fallback: Feed[] = [];
const { data = fallback } = useQuery({
queryKey: [queryKeys.feeds],
queryFn: getFeeds,
});
return data;
}
export function usePrefetchFeeds(): void {
const queryClient = useQueryClient();
queryClient.prefetchQuery({
queryKey: [queryKeys.feeds],
queryFn: getFeeds,
});
}
하위의 레이어들을 이용해 페이지에 사용되는 독립적인 UI 컴포넌트를 만드는 단계입니다.
-
FeedMainHeader.tsx
-
FeedMain.tsx
...
비즈니스 로직을 포함하는 View들이 이 단계에서 정의됩니다.
-
hooks/useLike.tsx
-
Like.tsx
-
FeedItem.tsx
...
비즈니스 엔티티를 정의합니다. 사용자, 리뷰 등이 포함됩니다.
- users/
- feeds/
재사용 가능한 컴포넌트와 유틸리티 함수, axios 설정 등이 여기에서 정의됩니다.
- axios: axios 설정이 포함된 디렉터리입니다.
// shared/axios/config.ts
import axios from "axios";
const SERVER_URL = process.env.REACT_APP_SERVER_URL;
export const axiosInstance = axios.create({
baseURL: '',
timeout: 20000,
headers: {
"Content-Type": "application/json",
accept: "application/json",
},
});
axiosInstance.interceptors.request.use(onRequest);
axiosInstance.interceptors.response.use(onResponse, onError);
- styles: scss의 전역 변수와 초기 설정이 위치하는 디렉터리입니다.
// shared/styles/font.scss
$font-large: 3rem;
$font-medium: 1.6rem;
$font-default: 1.2rem;
$font-small: 0.8rem;
// shared/styles/color.scss
$color-white: #ffffff;
$color-black: #000000;
$color-gray-400: #bdbdbd;
$color-gray-500: #9e9e9e;
$color-gray-700: #616161;
$color-red-400: #ef5350;
$color-red-500: #f44336;
$color-red-700: #d32f2f;
$color-blue-400: #42a5f5;
$color-blue-500: #2196f3;
$color-blue-700: #1976d2;
- ui: 자주 사용될 수 있는, View들이 위치하는 디렉터리입니다.
// shared/ui/Button.tsx
const Button = ({ onClick, color, data }) => {
return (
<button className="button-style" onClick={onClick}>
{data}
</button>
);
};
- util: 특정 비즈니스 로직에 종속되지 않은 유틸리티 함수가 포함된 디렉터리입니다.
// shared/util/key-factories.ts
export const generateUserKey = (userId: number) => {
return [queryKeys.user, userId];
};
export const generateUserAppointmentsKey = (
userId: number,
userToken: string
) => {
return [queryKeys.appointments, queryKeys.user, userId, userToken];
};