Skip to content

Commit e5816a2

Browse files
authored
충남대 FE_강병현_1주차_과제 Step1 (#18)
* docs(README.md): add a list of features * feat(kakao-gift): create TypeScript project using CRA Initialized a new project using Create React App with TypeScript template. * chore: remove unnecessary code and files Removed redundant code and deleted unused files to clean up the project. * chore: configure absolute paths using craco Set up absolute import paths using craco to simplify module imports and improve project structure. * chore: set up Prettier formatting rules Installed Prettier and configured formatting rules across the project. * chore: configure ESLint rules according Installed ESLint and set up rules to enforce coding standards and best practices throughout the project. * chore: add emotion styling library Installed @emotion/react and @emotion/styled as project dependencies. * feat: add Button component * feat: Apply reset CSS globally Added a global reset CSS file to normalize styles across the application. * feat: Initialize folder structure Created initial folder structure for the project. * chore: Moved files to new directory structure Organized project files into a new directory structure for better organization and maintainability. * feat: feat: Add lint-staged and husky Integrated lint-staged and husky to enforce linting and formatting on staged files before commits. * docs: Add feature list for Storybook components in README Added the detailed feature list for implementing reusable components using Storybook in the README file. The feature list includes: - Installation of Storybook - Implementation of Button component with theme, size, and basic attributes - Implementation of Input component with disabled, invalid, size, and basic attributes - Implementation of Image component with ratio, radius, and basic attributes * chore: install and configure Storybook * refactor(components): update Button component - Add customizable theme and size props - Update types for ButtonTheme and ButtonSize - Set default props for theme and size * design(Button): Implement button styling based on size props - Implemented conditional styling for button sizes using getSizeStyles function. - Applied responsive design for 'responsive' size using media queries. * design(Button): Implement button styling based on theme props - Implemented conditional styling for button theme using getThemeStyles function. * feat(storybook): add Button component story - Added Storybook configuration for the Button component - Implemented Button component stories with various themes and sizes * feat: add Input component * feat: add disabled prop styling to Input component * feat: add invalid prop styling to Input component * feat: implement size prop styling for Input component * feat: add Storybook stories for Input component * feat: add Image component * feat: add ratio prop to set image aspect ratio in Image component * feat: add radius prop to set border radius in Image component * feat: add width and height props to Image component * feat: add Storybook stories for RatioSquare, RadiusCircle, and RadiusRound in Image component * docs(README): add README documentation - Implement GoodsItem component with Default and Ranking variations - GoodsItem accepts common props: imageSrc, subtitle, title, amount - Ranking variation accepts additional rankingIndex prop - Display pink badge for rankingIndex 1-3 and gray badge for other numbers - Implement Grid component - Implement Container component * feat: implement GoodsItem component with common props - Implemented GoodsItem component - Accepts common props: imageSrc, subtitle, title, amount - Renders image, subtitle, title, and amount with the provided props * feat: add GoodsItem component * feat: add Ranking component * feat: add Storybook stories for GoodsItem Default and Ranking components * feat: add Container component * feat: add Storybook stories for Container component * feat: add FullScreen story for Container component * feat: add Grid component * feat: add NumberColumns story for Grid component * feat: add ResponsiveColumns story for Grid component * chore: move Button component file to common folder * chore: move files * docs: update README * feat: add autodocs tags to all Storybook files * fix: add babel-preset-react-app to package.json * docs: add requirements from code review to README * chore: remove eslintConfig from package.json * chore: move testing and types dependencies to devDependencies * docs: add initial folder structure explanation to README * chore: update lint script target * docs: create QUESTIONS.md * feat(button): update responsive height styles * refactor(ranking): remove magic number by defining a constant Replaced the magic number 3 used for ranking comparison with a constant TOP_RANKING_THRESHOLD to improve code readability and maintainability. * refactor(props): refactor all files to spread props for cleaner code * refactor(goods-item): replace magic numbers with constants Replaced magic numbers for image sizes with constants IMAGE_SIZE_LARGE and IMAGE_SIZE_SMALL to improve code readability and maintainability in the GoodsItem component. * chore: move styles folder to assets folder * fix(dependencies): add @babel/plugin-proposal-private-property-in-object to devDependencies Added @babel/plugin-proposal-private-property-in-object to devDependencies to resolve missing dependency issue in babel-preset-react-app. * refactor(GoodsItem): separate renderRanking method for better readability
1 parent 5f587bf commit e5816a2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+30322
-2
lines changed

.babelrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"plugins": ["@emotion"]
3+
}

.eslintrc

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
{
2+
"env": {
3+
"browser": true,
4+
"es2021": true
5+
},
6+
"extends": ["react-app", "eslint:recommended", "plugin:import/typescript", "airbnb", "prettier"],
7+
"parser": "@typescript-eslint/parser",
8+
"parserOptions": {
9+
"ecmaFeatures": {
10+
"jsx": true
11+
},
12+
"ecmaVersion": "latest",
13+
"sourceType": "module"
14+
},
15+
"rules": {
16+
"no-var": "error",
17+
"no-multiple-empty-lines": "error",
18+
"no-console": ["error", { "allow": ["warn", "error", "info"] }],
19+
"eqeqeq": "error",
20+
"dot-notation": "error",
21+
"no-unused-vars": "error",
22+
"import/extensions": ["error", "ignorePackages", {
23+
"js": "never",
24+
"jsx": "never",
25+
"ts": "never",
26+
"tsx": "never"
27+
}],
28+
"react/jsx-props-no-spreading": "off",
29+
"import/prefer-default-export": "off",
30+
"react/jsx-filename-extension": ["error", { "extensions": [".tsx"] }],
31+
"import/no-extraneous-dependencies": ["error", {"devDependencies": true}],
32+
"import/no-unresolved": "off",
33+
"react/require-default-props": "off",
34+
"no-use-before-define": "off",
35+
"@typescript-eslint/no-use-before-define": ["error", { "variables": false , "functions": false,"classes": false}],
36+
"react/prop-types": "off",
37+
"import/no-cycle": "off"
38+
},
39+
"settings": {
40+
"import/resolver": {
41+
"alias": {
42+
"map": [
43+
["@", "./src"],
44+
["@components", "./src/components"],
45+
["@styles", "./src/styles"],
46+
["@apis", "./src/apis"],
47+
["@assets", "./src/assets"],
48+
["@hooks", "./src/hooks"],
49+
["@pages", "./src/pages"],
50+
["@store", "./src/store"],
51+
["@utils", "./src/utils"]
52+
],
53+
"extensions": [".js", ".jsx", ".ts", ".tsx"]
54+
}
55+
}
56+
}
57+
}

.gitignore

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
10+
11+
# production
12+
/build
13+
14+
# misc
15+
.DS_Store
16+
.env.local
17+
.env.development.local
18+
.env.test.local
19+
.env.production.local
20+
21+
npm-debug.log*
22+
yarn-debug.log*
23+
yarn-error.log*
24+
25+
.eslintcache
26+
*storybook.log

.husky/pre-commit

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
npx lint-staged

.prettierrc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"singleQuote": true,
3+
"parser": "typescript",
4+
"semi": true,
5+
"useTabs": false,
6+
"tabWidth": 2,
7+
"printWidth": 120,
8+
"arrowParens": "always"
9+
}

.storybook/main.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import type { StorybookConfig } from '@storybook/react-webpack5';
2+
import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin';
3+
4+
const config: StorybookConfig = {
5+
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
6+
addons: [
7+
'@storybook/preset-create-react-app',
8+
'@storybook/addon-onboarding',
9+
'@storybook/addon-links',
10+
'@storybook/addon-essentials',
11+
'@chromatic-com/storybook',
12+
'@storybook/addon-interactions',
13+
],
14+
framework: {
15+
name: '@storybook/react-webpack5',
16+
options: {},
17+
},
18+
staticDirs: ['../public'],
19+
webpackFinal: async (config) => {
20+
if (config.resolve) {
21+
config.resolve.plugins = [
22+
...(config.resolve.plugins || []),
23+
new TsconfigPathsPlugin({
24+
extensions: config.resolve.extensions,
25+
}),
26+
];
27+
}
28+
return config;
29+
},
30+
};
31+
export default config;

.storybook/preview.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { Preview } from '@storybook/react';
2+
3+
const preview: Preview = {
4+
parameters: {
5+
controls: {
6+
matchers: {
7+
color: /(background|color)$/i,
8+
date: /Date$/i,
9+
},
10+
},
11+
},
12+
};
13+
14+
export default preview;

QUESTION.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
## 1주차 [질문](https://kibong.notion.site/db60b098e56e4333ae78e8c44edd09f5)
2+
3+
### 1. reportWebVital?
4+
이번 프로젝트를 세팅하면서 불필요한 파일을 탐색하던중 reportWeVital이라는 것을 알게되었는데요.
5+
찾아보니 웹 성능 측정을 통해서 사용자 경험과 성능 평가를 가능하게 해주는 도구임을 알게되었습니다.
6+
초기 React프로젝트를 reportWebVitals로 console로 간단하게 찍어보니 console탭에서 성능에 대한 결과를 객체 형태로 확인할 수 있었습니다.
7+
결과로 FCP, TTFB, LCP, FID, CLS와 같이 다양한 방면으로 성능 측정이 가능하다는 것을 확인할 수 있었습니다.
8+
이러한 웹 성능 측정을 회사에서 실제로 많이 고민하고 코드를 짜는지 궁금하고, 한번도 이런 성능 측정을 해본 경험이 없기에 이 부분에 대해서 더 자세히 알려면 어떤식으로, 어떻게 공부하고 경험할 수 있는지 궁금합니다.
9+
10+
### 2. 절대경로 ESLint 에러 이슈 어떻게 해결해야할까요?
11+
<img width="606" alt="스크린샷 2024-06-26 오후 5 44 42" src="https://github.com/kang-kibong/kang-kibong/assets/33623123/2acbd044-1698-4ffe-bc1b-bc4e0b9c2ae3">
12+
13+
ESLint가 `@components/Button.tsx` 모듈의 경로를 찾지 못하고 있었습니다.
14+
그 이유는 **alias reslover**가 제대로 설정되지 않아 생긴 문제였다고 판단하였습니다.
15+
때문에 두가지의 플러그인인 `eslint-plugin-import``eslint-import-resolver-alias`가 필요하다고 생각되어 설치를 진행했습니다.
16+
설치가 완료된 후 `.eslintrc`에서 **import/resolver/alias** 부분에 각 절대경로에 해당하는 aslias를 따로 지정해주어야 인식할 수 있기에 다음과 같이 작성해보았습니다.
17+
18+
```json
19+
{
20+
"env": {
21+
"browser": true,
22+
"es2021": true
23+
},
24+
"extends": ["react-app", "eslint:recommended", "plugin:import/typescript", "airbnb", "prettier"],
25+
"parser": "@typescript-eslint/parser",
26+
"parserOptions": {
27+
"ecmaFeatures": {
28+
"jsx": true
29+
},
30+
"ecmaVersion": "latest",
31+
"sourceType": "module"
32+
},
33+
"rules": {
34+
"no-var": "error",
35+
"no-multiple-empty-lines": "error",
36+
"no-console": ["error", { "allow": ["warn", "error", "info"] }],
37+
"eqeqeq": "error",
38+
"dot-notation": "error",
39+
"no-unused-vars": "error",
40+
"react/jsx-filename-extension": ["error", { "extensions": [".tsx"] }],
41+
"import/extensions": ["error", "ignorePackages"]
42+
},
43+
"settings": {
44+
**"import/resolver": {
45+
"alias": {
46+
"map": [
47+
["@components", "./src/components"]
48+
],
49+
"extensions": [".js", ".jsx", ".ts", ".tsx"]
50+
}
51+
}**
52+
}
53+
}
54+
```
55+
<img width="391" alt="스크린샷 2024-06-26 오후 5 47 23" src="https://github.com/kang-kibong/kang-kibong/assets/33623123/0af50065-124e-41d0-87e9-0d5302688883">
56+
57+
절대경로를 통해 발생한 ESLint가 사라진 것을 확인할 수 있었지만, 에디터를 닫고 다시 열어보니 같은 이슈가 발생하였습니다.
58+
59+
솔직히 이유를 잘 모르겠습니다.
60+
61+
구글링해본 결과 일단 `rules``"import/no-unresolved": "off”`하면 해결할 수 있다고 하여 작성해놓은 상태입니다.
62+
63+
이 이슈를 해결할 수 있는 방안은 무엇일까요?
64+
65+
### 3. Emotion의 styled 작성은 어떤것을 선호하시나요?
66+
67+
css-in-js인 만큼 자바스크립트 안에 스타일 코드를 작성할 수 있다는 점에서 장점이있다고 생각합니다.
68+
69+
하지만 책임분리를 생각해보면 스타일만 책임을 갖는 파일로 분리하는 것이 좋을지 아니면 컴포넌트 하단에 스타일 코드를 작성해야하는지 궁금합니다.
70+
71+
개인적으로 저는 컴포넌트 코드를 확인하면서 스타일링 작업을 해야되서 위, 아래로 자주 스크롤하는 것이, 생각보다 개발 효율이 안좋아서 책임 분리라는 이유로? 다음과 같이 스타일 코드 파일을 분리하여 작업하고 있습니다.
72+
```json
73+
Button
74+
├── Button.styled.ts
75+
└── Button.tsx
76+
```
77+
78+
보통 어떤식으로 하는지 궁금합니다! 정답이란게 있을까요?
79+
80+
### 4. Emotion의 babel-plugin을 사용하는 이유는 무엇인가요?
81+
82+
스타일을 압축 및 호이스팅하여 최적화하고 souce map및 label로 더나은 개발 경험을 생성하는 플러그인을 원하면 권장한다고 합니다.
83+
84+
해당 내용에 대해서 잘 이해가 가지 않아 고민입니다!
85+
86+
### 5. tailwindcss와 css-in-js에서의 고민
87+
88+
요즘 채용공고를 보면 이전과는 다르게 심심치않게 tailwindcss를 요구하는 회사가 많아지고 있다는 것을 느꼈습니다.
89+
90+
이러한 동향이 발생된 멘토님의 개인적인 이유를 들어보고 싶습니다.
91+
92+
개인적으로 tailwindcss는 inline css와 같이 클래스명 내에서 스타일링할 수 있다는 점에서 유지보수하기 힘들 것 같다는 생각에 평소 css-in-js를 많이 사용하는 것 같습니다.
93+
94+
성능 차이에서일까요? 아니면 편의성때문일까요? 두 라이브러리에 대한 차이에 대해서도 궁금합니다.
95+
96+
### 6. lint-staged, husky 현업에서 많이 사용하고있나요?
97+
98+
eslint와 prettier를 공부하던 중 lint-staged와 huksy에 대해서 알게되었습니다.
99+
100+
이번 과제에서도 적용해보았지만, 이를 고려하면 git hook을 통해 포맷팅와 린팅을 자동화 시킬 수 있다는 점이 장점이라 생각되어 다른 프로젝트에서도 평소 사용하고 있는 편입니다.
101+
102+
현업에서도 많이 쓰이는 기술일까요? 아니면 이것도 필요에 따라 설치하는 편인가요?
103+
104+
### 7. 폴더 구조에는 정답이란게 있을까요?
105+
106+
코드를 작성하다보면 분리를 할 수 있는 상황이 되는데요. 이럴때마다 어떤 폴더로 관리해야되는지 감이 잘 안오는 것 같습니다.
107+
108+
그 이유를 생각해보니 React가 라이브러리라는 특성을 가진 만큼 규격이 딱히 정해져 있지 않다보니 사람마다 천차만별로 관리하는 것 같다고 생각해서인 것 같습니다.
109+
110+
이번 과제에서는 기능에 따라 패턴을 잡아봤습니다.
111+
112+
혹시 정답이란게 있을까요? 혹은 최근 많이 사용되어지고 있는 패턴이 있을까요?

README.md

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,91 @@
1-
# react-gift-react-foundation
2-
FE 카카오 선물하기 1주차 과제: React 기초
1+
# 1️⃣ 1주차 프로젝트 세팅 & 컴포넌트 - React 입문
2+
## ⚙️ 1단계 - 프로젝트 세팅
3+
### 📄 기능 목록
4+
- [x] CRA 기반 TypeScript 프로젝트 생성
5+
- [x] 절대 경로 설정
6+
- [x] prettier 설치 및 룰 설정
7+
- [x] eslint 설치 및 eslint-config-airbnb 룰 설정
8+
- [x] lint-staged, husky 설치 및 자동화 설정
9+
- [x] emotion 스타일 라이브러리 설치
10+
- [x] reset css 적용
11+
- [x] .gitignore 추가
12+
- [x] 불필요한 코드 및 파일 정리
13+
- [x] 폴더 구조 생성
14+
- apis: Axios 인스턴스 설정 파일 등 API 관련 설정 파일을 관리합니다.
15+
- assets: 이미지, 폰트, 아이콘 등의 정적 파일을 관리합니다.
16+
- styles: 글로벌 스타일 설정 파일입니다. 기본 스타일을 재설정하거나 공통 스타일을 정의합니다.
17+
- components: 컴포넌트를 모아놓은 디렉토리입니다.
18+
- common: 공통 컴포넌트를 모아놓은 디렉토리입니다.
19+
- hooks: 커스텀 훅을 모아놓은 디렉토리입니다.
20+
- pages: 페이지 컴포넌트를 모아놓은 디렉토리입니다. 각 페이지는 일반적으로 라우팅의 엔드포인트가 됩니다.
21+
- store: 애플리케이션의 전체 상태 관리를 위한 스토어 파일입니다.
22+
- utils: 유틸리티 함수들을 모아놓은 파일입니다.
23+
- constants: 애플리케이션 전반에서 사용되는 상수들을 정의합니다.
24+
25+
## 📕 2단계 - Storybook을 사용하여 재사용 가능한 컴포넌트 구현
26+
### 📄 기능 목록
27+
- [x] Stroybook 설치
28+
- [x] Button 컴포넌트 구현
29+
- [x] theme props에 따른 버튼 컬러와 디자인이 다르게 구현
30+
- [x] size props에 따른 버튼의 크기를 다르게 구현(value가 responsive인 경우 미디어 쿼리에 따라 사이즈가 다르게 구현)
31+
- [x] Button 기본 속성들을 모두 사용할 수 있게 Storybook 구현
32+
- [x] Input 컴포넌트 구현
33+
- [x] disabled props에 따른 비활성화 및 디자인 구현
34+
- [x] invalid props에 따른 값이 잘못되었음을 디자인하도록 구현
35+
- [x] size props에 따라 버튼의 크기를 다르게 구현(value가 responsive인 경우 미디어 쿼리에 따라 사이즈가 다르게 구현)
36+
- [x] Input 기본 속성들을 모두 사용할 수 있게 구현
37+
- [x] Image 컴포넌트 구현
38+
- [x] ratio props에 따른 이미지 비율을 설정할 수 있도록 구현(value가 number로 16/9로 넘겨진 경우 16:9비율로 보여짐, square을 설정한 경우 정사각형으로 보여짐)
39+
- [x] raduis props에 따른 모서리를 둥글게 구현(value가 number인 경우 number만큼 모서리가 둥글게 적용, circle인 경우 원형으로 보여짐)
40+
- [x] Img 기본 속성들을 모두 사용할 수 있게 구현
41+
- [x] GoodsItem 컴포넌트 구현
42+
- [x] Default 형태와 Ranking 형태의 컴포넌트를 각각 구현 (자세한 디자인은 스토리북 참고)
43+
- [x] 공통으로 imageSrc, subtitle, title, amount Props를 넘겨 받음
44+
- [x] Ranking 컴포넌트의 경우 rankingIndex Props를 추가로 넘겨 받음. 1~3까지는 분홍색, 나머지 숫자에는 회색의 랭킹 뱃지가 보여짐
45+
- [x] Container 컴포넌트 구현
46+
- [x] Container 스토리북 구현
47+
- [x] FullScreen 스토리북 구현
48+
- [x] Grid 컴포넌트를 구현
49+
- [x] NumberColumns 스토리북 구현
50+
- [x] ResponsiveColumns 스토리북 구현
51+
52+
53+
## 🤔 3단계 - 질문의 답변을 README에 작성
54+
### 질문 1: Webpack은 무엇이고 어떤 역할을 하고 있나요?
55+
56+
Webpack은 모듈 번들러로, 여러 개의 파일과 그 파일들 간의 종속성을 하나의 파일이나 여러 개의 파일로 묶어서 웹 애플리케이션에 필요한 리소스를 효율적으로 제공합니다.
57+
58+
### Webpack의 주요 역할:
59+
60+
1. **번들링:** 여러 자바스크립트 파일을 하나 또는 여러 개의 번들로 결합하여 최적화합니다. 이를 통해 네트워크 요청 수를 줄이고 로딩 시간을 단축할 수 있습니다.
61+
2. **모듈 의존성 관리:** 파일 간의 종속성을 분석하고 올바른 순서로 결합하여 코드를 모듈화하고 관리하기 쉽게 만듭니다.
62+
3. **로드 및 변환:** 로더를 사용해 다양한 파일 형식을 처리합니다. 예를 들어, Babel 로더를 사용해 최신 자바스크립트 코드를 브라우저가 이해할 수 있는 코드로 변환합니다.
63+
4. **플러그인 시스템:** 플러그인을 통해 번들링 과정 중 파일 크기 압축, 코드 스플리팅, 핫 모듈 교체(HMR) 등의 작업을 수행할 수 있습니다.
64+
65+
### 질문 2: 브라우저는 어떻게 JSX 파일을 읽을 수 있나요?
66+
67+
브라우저는 기본적으로 JSX 파일을 직접 읽을 수 없습니다. JSX는 JavaScript의 확장 문법으로, 이를 일반 JavaScript 코드로 변환해야 합니다.
68+
69+
### 변환 과정:
70+
71+
1. **Babel:** JSX를 JavaScript 코드로 변환합니다. Babel은 JSX 문법을 React.createElement() 함수 호출로 변환하여 브라우저가 이해할 수 있는 순수 JavaScript 코드로 바꿉니다.
72+
2. **Webpack과 Babel 통합:** Webpack의 Babel 로더를 사용해 프로젝트의 모든 JSX 파일을 JavaScript로 변환합니다. Webpack은 종속성을 분석하고, Babel을 사용해 JSX 파일을 변환한 후 번들링합니다.
73+
3. **번들된 JavaScript 파일:** 최종적으로 변환된 JavaScript 코드는 하나의 번들 파일로 묶여 브라우저에서 실행됩니다.
74+
75+
### 질문 3: React에서 상태 변화가 생겼을 때 어떻게 변화를 알아챌 수 있나요?
76+
77+
React는 상태 변화(state change)를 감지하고, 이에 따라 컴포넌트를 업데이트합니다. 상태 변화가 발생했을 때 변화를 알아채는 메커니즘은 다음과 같습니다:
78+
79+
1. **setState 또는 useState:** 클래스 컴포넌트에서는 `this.setState`를, 함수형 컴포넌트에서는 `useState`를 사용해 상태를 업데이트합니다.
80+
2. **상태 변화 감지:** `setState` 또는 `useState`를 호출하면 React는 상태 변경을 감지합니다. 이전 상태와 새로운 상태를 비교하여 실제로 변경이 발생했는지 확인합니다.
81+
3. **리렌더링:** 상태 변화가 감지되면 해당 컴포넌트와 자식 컴포넌트가 다시 렌더링됩니다. React는 가상 DOM을 사용해 새로운 상태를 반영한 가상 DOM 트리를 생성하고, 이전 가상 DOM과 비교하여 실제 DOM에서 변경이 필요한 부분만 업데이트합니다.
82+
4. **최적화 기법:** React는 불필요한 리렌더링을 방지하기 위해 `shouldComponentUpdate`, `React.memo`, `useMemo`, `useCallback` 등을 사용하여 변경된 부분만 효율적으로 업데이트합니다.
83+
84+
## 🛠️ 코드 리뷰 반영
85+
### 📄 요구 사항
86+
- [x] babel-preset-react-app 설치
87+
- [x] package.json의 eslintConfig 제거
88+
- [x] testing library와 typescript 패키지 devdependencies로 변경
89+
- [x] README에 초기 폴더 구조에 대한 설명 기재
90+
- [x] lint 대상 변경
91+
- [x] QUESTION.md 추가

craco.config.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const path = require('path');
2+
3+
module.exports = {
4+
webpack: {
5+
alias: {
6+
'@': path.resolve(__dirname, 'src/'),
7+
'@components': path.resolve(__dirname, 'src/components'),
8+
'@styles': path.resolve(__dirname, 'src/styles'),
9+
'@apis': path.resolve(__dirname, 'src/apis'),
10+
'@assets': path.resolve(__dirname, 'src/assets'),
11+
'@hooks': path.resolve(__dirname, 'src/hooks'),
12+
'@pages': path.resolve(__dirname, 'src/pages'),
13+
'@store': path.resolve(__dirname, 'src/store'),
14+
'@utils': path.resolve(__dirname, 'src/utils'),
15+
},
16+
},
17+
};

0 commit comments

Comments
 (0)