-
Notifications
You must be signed in to change notification settings - Fork 51
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
충남대 FE_강병현_1주차_과제 Step1 #18
Changes from all commits
3a896a3
586a145
9a6f829
f22f89e
dc76831
45a3b22
de2ffcc
2ae3ea8
b5fcaed
5ef0d54
f558c4e
2317065
4840d6a
ddc3fff
f9747a7
bc5c112
c7e61b0
c7b8991
af20619
6dd2c28
76fcdd0
df88036
4621a85
0213fc5
41eede0
74bec12
563337a
166a65e
e0158a9
3f8b081
4f57ac9
bcb5659
0a1ea6d
dfdaebe
5ef7785
3058f54
dcaeca4
daf0158
b38ee04
571bacf
3872a5c
e524f7d
69d09a4
997a79a
a9c4096
65a4214
def5518
ce11642
9abf298
43c723b
02fd425
ab9c04c
60a07c4
3d13ff9
2c9105b
ab6680f
a06d91e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"plugins": ["@emotion"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
{ | ||
"env": { | ||
"browser": true, | ||
"es2021": true | ||
}, | ||
"extends": ["react-app", "eslint:recommended", "plugin:import/typescript", "airbnb", "prettier"], | ||
"parser": "@typescript-eslint/parser", | ||
"parserOptions": { | ||
"ecmaFeatures": { | ||
"jsx": true | ||
}, | ||
"ecmaVersion": "latest", | ||
"sourceType": "module" | ||
}, | ||
"rules": { | ||
"no-var": "error", | ||
"no-multiple-empty-lines": "error", | ||
"no-console": ["error", { "allow": ["warn", "error", "info"] }], | ||
"eqeqeq": "error", | ||
"dot-notation": "error", | ||
"no-unused-vars": "error", | ||
"import/extensions": ["error", "ignorePackages", { | ||
"js": "never", | ||
"jsx": "never", | ||
"ts": "never", | ||
"tsx": "never" | ||
}], | ||
"react/jsx-props-no-spreading": "off", | ||
"import/prefer-default-export": "off", | ||
"react/jsx-filename-extension": ["error", { "extensions": [".tsx"] }], | ||
"import/no-extraneous-dependencies": ["error", {"devDependencies": true}], | ||
"import/no-unresolved": "off", | ||
"react/require-default-props": "off", | ||
"no-use-before-define": "off", | ||
"@typescript-eslint/no-use-before-define": ["error", { "variables": false , "functions": false,"classes": false}], | ||
"react/prop-types": "off", | ||
"import/no-cycle": "off" | ||
}, | ||
"settings": { | ||
"import/resolver": { | ||
"alias": { | ||
"map": [ | ||
["@", "./src"], | ||
["@components", "./src/components"], | ||
["@styles", "./src/styles"], | ||
["@apis", "./src/apis"], | ||
["@assets", "./src/assets"], | ||
["@hooks", "./src/hooks"], | ||
["@pages", "./src/pages"], | ||
["@store", "./src/store"], | ||
["@utils", "./src/utils"] | ||
], | ||
"extensions": [".js", ".jsx", ".ts", ".tsx"] | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# testing | ||
/coverage | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
.env.local | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
|
||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
.eslintcache | ||
*storybook.log |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
npx lint-staged |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"singleQuote": true, | ||
"parser": "typescript", | ||
"semi": true, | ||
"useTabs": false, | ||
"tabWidth": 2, | ||
"printWidth": 120, | ||
"arrowParens": "always" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import type { StorybookConfig } from '@storybook/react-webpack5'; | ||
import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin'; | ||
|
||
const config: StorybookConfig = { | ||
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], | ||
addons: [ | ||
'@storybook/preset-create-react-app', | ||
'@storybook/addon-onboarding', | ||
'@storybook/addon-links', | ||
'@storybook/addon-essentials', | ||
'@chromatic-com/storybook', | ||
'@storybook/addon-interactions', | ||
], | ||
framework: { | ||
name: '@storybook/react-webpack5', | ||
options: {}, | ||
}, | ||
staticDirs: ['../public'], | ||
webpackFinal: async (config) => { | ||
if (config.resolve) { | ||
config.resolve.plugins = [ | ||
...(config.resolve.plugins || []), | ||
new TsconfigPathsPlugin({ | ||
extensions: config.resolve.extensions, | ||
}), | ||
]; | ||
} | ||
return config; | ||
}, | ||
}; | ||
export default config; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import type { Preview } from '@storybook/react'; | ||
|
||
const preview: Preview = { | ||
parameters: { | ||
controls: { | ||
matchers: { | ||
color: /(background|color)$/i, | ||
date: /Date$/i, | ||
}, | ||
}, | ||
}, | ||
}; | ||
|
||
export default preview; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
## 1주차 [질문](https://kibong.notion.site/db60b098e56e4333ae78e8c44edd09f5) | ||
|
||
### 1. reportWebVital? | ||
이번 프로젝트를 세팅하면서 불필요한 파일을 탐색하던중 reportWeVital이라는 것을 알게되었는데요. | ||
찾아보니 웹 성능 측정을 통해서 사용자 경험과 성능 평가를 가능하게 해주는 도구임을 알게되었습니다. | ||
초기 React프로젝트를 reportWebVitals로 console로 간단하게 찍어보니 console탭에서 성능에 대한 결과를 객체 형태로 확인할 수 있었습니다. | ||
결과로 FCP, TTFB, LCP, FID, CLS와 같이 다양한 방면으로 성능 측정이 가능하다는 것을 확인할 수 있었습니다. | ||
이러한 웹 성능 측정을 회사에서 실제로 많이 고민하고 코드를 짜는지 궁금하고, 한번도 이런 성능 측정을 해본 경험이 없기에 이 부분에 대해서 더 자세히 알려면 어떤식으로, 어떻게 공부하고 경험할 수 있는지 궁금합니다. | ||
|
||
### 2. 절대경로 ESLint 에러 이슈 어떻게 해결해야할까요? | ||
<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"> | ||
|
||
ESLint가 `@components/Button.tsx` 모듈의 경로를 찾지 못하고 있었습니다. | ||
그 이유는 **alias reslover**가 제대로 설정되지 않아 생긴 문제였다고 판단하였습니다. | ||
때문에 두가지의 플러그인인 `eslint-plugin-import`와 `eslint-import-resolver-alias`가 필요하다고 생각되어 설치를 진행했습니다. | ||
설치가 완료된 후 `.eslintrc`에서 **import/resolver/alias** 부분에 각 절대경로에 해당하는 aslias를 따로 지정해주어야 인식할 수 있기에 다음과 같이 작성해보았습니다. | ||
|
||
```json | ||
{ | ||
"env": { | ||
"browser": true, | ||
"es2021": true | ||
}, | ||
"extends": ["react-app", "eslint:recommended", "plugin:import/typescript", "airbnb", "prettier"], | ||
"parser": "@typescript-eslint/parser", | ||
"parserOptions": { | ||
"ecmaFeatures": { | ||
"jsx": true | ||
}, | ||
"ecmaVersion": "latest", | ||
"sourceType": "module" | ||
}, | ||
"rules": { | ||
"no-var": "error", | ||
"no-multiple-empty-lines": "error", | ||
"no-console": ["error", { "allow": ["warn", "error", "info"] }], | ||
"eqeqeq": "error", | ||
"dot-notation": "error", | ||
"no-unused-vars": "error", | ||
"react/jsx-filename-extension": ["error", { "extensions": [".tsx"] }], | ||
"import/extensions": ["error", "ignorePackages"] | ||
}, | ||
"settings": { | ||
**"import/resolver": { | ||
"alias": { | ||
"map": [ | ||
["@components", "./src/components"] | ||
], | ||
"extensions": [".js", ".jsx", ".ts", ".tsx"] | ||
} | ||
}** | ||
} | ||
} | ||
``` | ||
<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"> | ||
|
||
절대경로를 통해 발생한 ESLint가 사라진 것을 확인할 수 있었지만, 에디터를 닫고 다시 열어보니 같은 이슈가 발생하였습니다. | ||
|
||
솔직히 이유를 잘 모르겠습니다. | ||
|
||
구글링해본 결과 일단 `rules`에 `"import/no-unresolved": "off”`하면 해결할 수 있다고 하여 작성해놓은 상태입니다. | ||
|
||
이 이슈를 해결할 수 있는 방안은 무엇일까요? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 2번 문제는 |
||
|
||
### 3. Emotion의 styled 작성은 어떤것을 선호하시나요? | ||
|
||
css-in-js인 만큼 자바스크립트 안에 스타일 코드를 작성할 수 있다는 점에서 장점이있다고 생각합니다. | ||
|
||
하지만 책임분리를 생각해보면 스타일만 책임을 갖는 파일로 분리하는 것이 좋을지 아니면 컴포넌트 하단에 스타일 코드를 작성해야하는지 궁금합니다. | ||
|
||
개인적으로 저는 컴포넌트 코드를 확인하면서 스타일링 작업을 해야되서 위, 아래로 자주 스크롤하는 것이, 생각보다 개발 효율이 안좋아서 책임 분리라는 이유로? 다음과 같이 스타일 코드 파일을 분리하여 작업하고 있습니다. | ||
```json | ||
Button | ||
├── Button.styled.ts | ||
└── Button.tsx | ||
``` | ||
|
||
보통 어떤식으로 하는지 궁금합니다! 정답이란게 있을까요? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 책임 분리를 통해 얻는 이점이 무엇인지 명확히 할 필요가 있겠습니다. 어떤 이점이 있을까요? |
||
|
||
### 4. Emotion의 babel-plugin을 사용하는 이유는 무엇인가요? | ||
|
||
스타일을 압축 및 호이스팅하여 최적화하고 souce map및 label로 더나은 개발 경험을 생성하는 플러그인을 원하면 권장한다고 합니다. | ||
|
||
해당 내용에 대해서 잘 이해가 가지 않아 고민입니다! | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 혹시 https://emotion.sh/docs/@emotion/babel-plugin 내용 읽어보셨을까요? |
||
|
||
### 5. tailwindcss와 css-in-js에서의 고민 | ||
|
||
요즘 채용공고를 보면 이전과는 다르게 심심치않게 tailwindcss를 요구하는 회사가 많아지고 있다는 것을 느꼈습니다. | ||
|
||
이러한 동향이 발생된 멘토님의 개인적인 이유를 들어보고 싶습니다. | ||
|
||
개인적으로 tailwindcss는 inline css와 같이 클래스명 내에서 스타일링할 수 있다는 점에서 유지보수하기 힘들 것 같다는 생각에 평소 css-in-js를 많이 사용하는 것 같습니다. | ||
|
||
성능 차이에서일까요? 아니면 편의성때문일까요? 두 라이브러리에 대한 차이에 대해서도 궁금합니다. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 혹시 Utility-First Fundamentals 읽어보셨을까요? 읽어보신 뒤의 병현 님 생각도 궁금합니다. 추가로 CSS-in-JS, 무엇이 다른가요? 글도 추천드립니다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tailwindcss와 css-in-js 의 선택은 프로젝트의 요구사항과 팀의 선호도에 따라 달라질 수 있다는 생각이 들었습니다. tailwindcss의 장점은 클래스명에 대해 고민할 필요가 없고, 제공하는 유틸리티 클래스를 사용하여 반응형 디자인과 이벤트 처리를 더욱 간결하게 작성할 수 있다는 점인 것 같습니다. 때문에 기존 CSS를 사용하면 길어지는 코드를 획기적으로 줄일 수 있는점과 css-in-js와는 다르게 모든 클래스를 빌드시간에 생성하기 때문에 성능면에서 좋다는 생각이 들었습니다. 그러나 러닝 커브가 존재하기 때문에 팀원 모두가 사용법에 대해 숙지해야 한다는 점이 있는 것 같습니다. css-in-js, 특히 styled-components는 동적으로 스타일링하기에 최적화되어 있있는 것 같고 낮은 러닝 커브가 장점인 것 같습니다. |
||
|
||
### 6. lint-staged, husky 현업에서 많이 사용하고있나요? | ||
|
||
eslint와 prettier를 공부하던 중 lint-staged와 huksy에 대해서 알게되었습니다. | ||
|
||
이번 과제에서도 적용해보았지만, 이를 고려하면 git hook을 통해 포맷팅와 린팅을 자동화 시킬 수 있다는 점이 장점이라 생각되어 다른 프로젝트에서도 평소 사용하고 있는 편입니다. | ||
|
||
현업에서도 많이 쓰이는 기술일까요? 아니면 이것도 필요에 따라 설치하는 편인가요? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 보통 많이 씁니다. 커밋할 때 eslint, prettier 적용하고 CI에서 잘 적용됐는지 eslint, prettier 실행해서 체크하는 과정을 거치게 되는데 적용하지 않으면 CI에서 깨질 수 있으니까요. |
||
|
||
### 7. 폴더 구조에는 정답이란게 있을까요? | ||
|
||
코드를 작성하다보면 분리를 할 수 있는 상황이 되는데요. 이럴때마다 어떤 폴더로 관리해야되는지 감이 잘 안오는 것 같습니다. | ||
|
||
그 이유를 생각해보니 React가 라이브러리라는 특성을 가진 만큼 규격이 딱히 정해져 있지 않다보니 사람마다 천차만별로 관리하는 것 같다고 생각해서인 것 같습니다. | ||
|
||
이번 과제에서는 기능에 따라 패턴을 잡아봤습니다. | ||
|
||
혹시 정답이란게 있을까요? 혹은 최근 많이 사용되어지고 있는 패턴이 있을까요? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아래 글들 읽어보시고 한번 병현님 생각 전달해봐주시겠어요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 일단 “폴더 구조에 대한 정답은 없다.”인 것 같습니다. 그러나 도움이 되는 방법 중 하나는 colocation을 적용하는 것인 것 같습니다. 처음에는 관련된 기능을 하나의 폴더에 모아 작업을 진행하다가, 점차 프로젝트가 커지면 관련된 파일들을 가능한 한 가까운 곳에 배치하는 것이 좋다는 것으로 이해했습니다. 이후에는 특정 기능을 수정할 때 수정해야 할 파일이 어디에 있는지 명확하게 예측할 수 있기 때문에 시간이 단축되고 작업 용이성이 향상될 수 있다는 생각이 들었습니다! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,91 @@ | ||
# react-gift-react-foundation | ||
FE 카카오 선물하기 1주차 과제: React 기초 | ||
# 1️⃣ 1주차 프로젝트 세팅 & 컴포넌트 - React 입문 | ||
## ⚙️ 1단계 - 프로젝트 세팅 | ||
### 📄 기능 목록 | ||
- [x] CRA 기반 TypeScript 프로젝트 생성 | ||
- [x] 절대 경로 설정 | ||
- [x] prettier 설치 및 룰 설정 | ||
- [x] eslint 설치 및 eslint-config-airbnb 룰 설정 | ||
- [x] lint-staged, husky 설치 및 자동화 설정 | ||
- [x] emotion 스타일 라이브러리 설치 | ||
- [x] reset css 적용 | ||
- [x] .gitignore 추가 | ||
- [x] 불필요한 코드 및 파일 정리 | ||
- [x] 폴더 구조 생성 | ||
taehwanno marked this conversation as resolved.
Show resolved
Hide resolved
taehwanno marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- apis: Axios 인스턴스 설정 파일 등 API 관련 설정 파일을 관리합니다. | ||
- assets: 이미지, 폰트, 아이콘 등의 정적 파일을 관리합니다. | ||
- styles: 글로벌 스타일 설정 파일입니다. 기본 스타일을 재설정하거나 공통 스타일을 정의합니다. | ||
- components: 컴포넌트를 모아놓은 디렉토리입니다. | ||
- common: 공통 컴포넌트를 모아놓은 디렉토리입니다. | ||
- hooks: 커스텀 훅을 모아놓은 디렉토리입니다. | ||
- pages: 페이지 컴포넌트를 모아놓은 디렉토리입니다. 각 페이지는 일반적으로 라우팅의 엔드포인트가 됩니다. | ||
- store: 애플리케이션의 전체 상태 관리를 위한 스토어 파일입니다. | ||
- utils: 유틸리티 함수들을 모아놓은 파일입니다. | ||
- constants: 애플리케이션 전반에서 사용되는 상수들을 정의합니다. | ||
|
||
## 📕 2단계 - Storybook을 사용하여 재사용 가능한 컴포넌트 구현 | ||
### 📄 기능 목록 | ||
- [x] Stroybook 설치 | ||
- [x] Button 컴포넌트 구현 | ||
- [x] theme props에 따른 버튼 컬러와 디자인이 다르게 구현 | ||
- [x] size props에 따른 버튼의 크기를 다르게 구현(value가 responsive인 경우 미디어 쿼리에 따라 사이즈가 다르게 구현) | ||
- [x] Button 기본 속성들을 모두 사용할 수 있게 Storybook 구현 | ||
- [x] Input 컴포넌트 구현 | ||
- [x] disabled props에 따른 비활성화 및 디자인 구현 | ||
- [x] invalid props에 따른 값이 잘못되었음을 디자인하도록 구현 | ||
- [x] size props에 따라 버튼의 크기를 다르게 구현(value가 responsive인 경우 미디어 쿼리에 따라 사이즈가 다르게 구현) | ||
- [x] Input 기본 속성들을 모두 사용할 수 있게 구현 | ||
- [x] Image 컴포넌트 구현 | ||
- [x] ratio props에 따른 이미지 비율을 설정할 수 있도록 구현(value가 number로 16/9로 넘겨진 경우 16:9비율로 보여짐, square을 설정한 경우 정사각형으로 보여짐) | ||
- [x] raduis props에 따른 모서리를 둥글게 구현(value가 number인 경우 number만큼 모서리가 둥글게 적용, circle인 경우 원형으로 보여짐) | ||
- [x] Img 기본 속성들을 모두 사용할 수 있게 구현 | ||
- [x] GoodsItem 컴포넌트 구현 | ||
- [x] Default 형태와 Ranking 형태의 컴포넌트를 각각 구현 (자세한 디자인은 스토리북 참고) | ||
- [x] 공통으로 imageSrc, subtitle, title, amount Props를 넘겨 받음 | ||
- [x] Ranking 컴포넌트의 경우 rankingIndex Props를 추가로 넘겨 받음. 1~3까지는 분홍색, 나머지 숫자에는 회색의 랭킹 뱃지가 보여짐 | ||
- [x] Container 컴포넌트 구현 | ||
- [x] Container 스토리북 구현 | ||
- [x] FullScreen 스토리북 구현 | ||
- [x] Grid 컴포넌트를 구현 | ||
- [x] NumberColumns 스토리북 구현 | ||
- [x] ResponsiveColumns 스토리북 구현 | ||
|
||
|
||
## 🤔 3단계 - 질문의 답변을 README에 작성 | ||
### 질문 1: Webpack은 무엇이고 어떤 역할을 하고 있나요? | ||
|
||
Webpack은 모듈 번들러로, 여러 개의 파일과 그 파일들 간의 종속성을 하나의 파일이나 여러 개의 파일로 묶어서 웹 애플리케이션에 필요한 리소스를 효율적으로 제공합니다. | ||
|
||
### Webpack의 주요 역할: | ||
|
||
1. **번들링:** 여러 자바스크립트 파일을 하나 또는 여러 개의 번들로 결합하여 최적화합니다. 이를 통해 네트워크 요청 수를 줄이고 로딩 시간을 단축할 수 있습니다. | ||
2. **모듈 의존성 관리:** 파일 간의 종속성을 분석하고 올바른 순서로 결합하여 코드를 모듈화하고 관리하기 쉽게 만듭니다. | ||
3. **로드 및 변환:** 로더를 사용해 다양한 파일 형식을 처리합니다. 예를 들어, Babel 로더를 사용해 최신 자바스크립트 코드를 브라우저가 이해할 수 있는 코드로 변환합니다. | ||
4. **플러그인 시스템:** 플러그인을 통해 번들링 과정 중 파일 크기 압축, 코드 스플리팅, 핫 모듈 교체(HMR) 등의 작업을 수행할 수 있습니다. | ||
|
||
### 질문 2: 브라우저는 어떻게 JSX 파일을 읽을 수 있나요? | ||
|
||
브라우저는 기본적으로 JSX 파일을 직접 읽을 수 없습니다. JSX는 JavaScript의 확장 문법으로, 이를 일반 JavaScript 코드로 변환해야 합니다. | ||
|
||
### 변환 과정: | ||
|
||
1. **Babel:** JSX를 JavaScript 코드로 변환합니다. Babel은 JSX 문법을 React.createElement() 함수 호출로 변환하여 브라우저가 이해할 수 있는 순수 JavaScript 코드로 바꿉니다. | ||
2. **Webpack과 Babel 통합:** Webpack의 Babel 로더를 사용해 프로젝트의 모든 JSX 파일을 JavaScript로 변환합니다. Webpack은 종속성을 분석하고, Babel을 사용해 JSX 파일을 변환한 후 번들링합니다. | ||
3. **번들된 JavaScript 파일:** 최종적으로 변환된 JavaScript 코드는 하나의 번들 파일로 묶여 브라우저에서 실행됩니다. | ||
|
||
### 질문 3: React에서 상태 변화가 생겼을 때 어떻게 변화를 알아챌 수 있나요? | ||
|
||
React는 상태 변화(state change)를 감지하고, 이에 따라 컴포넌트를 업데이트합니다. 상태 변화가 발생했을 때 변화를 알아채는 메커니즘은 다음과 같습니다: | ||
|
||
1. **setState 또는 useState:** 클래스 컴포넌트에서는 `this.setState`를, 함수형 컴포넌트에서는 `useState`를 사용해 상태를 업데이트합니다. | ||
2. **상태 변화 감지:** `setState` 또는 `useState`를 호출하면 React는 상태 변경을 감지합니다. 이전 상태와 새로운 상태를 비교하여 실제로 변경이 발생했는지 확인합니다. | ||
3. **리렌더링:** 상태 변화가 감지되면 해당 컴포넌트와 자식 컴포넌트가 다시 렌더링됩니다. React는 가상 DOM을 사용해 새로운 상태를 반영한 가상 DOM 트리를 생성하고, 이전 가상 DOM과 비교하여 실제 DOM에서 변경이 필요한 부분만 업데이트합니다. | ||
4. **최적화 기법:** React는 불필요한 리렌더링을 방지하기 위해 `shouldComponentUpdate`, `React.memo`, `useMemo`, `useCallback` 등을 사용하여 변경된 부분만 효율적으로 업데이트합니다. | ||
|
||
## 🛠️ 코드 리뷰 반영 | ||
### 📄 요구 사항 | ||
- [x] babel-preset-react-app 설치 | ||
- [x] package.json의 eslintConfig 제거 | ||
- [x] testing library와 typescript 패키지 devdependencies로 변경 | ||
- [x] README에 초기 폴더 구조에 대한 설명 기재 | ||
- [x] lint 대상 변경 | ||
- [x] QUESTION.md 추가 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
const path = require('path'); | ||
|
||
module.exports = { | ||
webpack: { | ||
alias: { | ||
'@': path.resolve(__dirname, 'src/'), | ||
'@components': path.resolve(__dirname, 'src/components'), | ||
'@styles': path.resolve(__dirname, 'src/styles'), | ||
'@apis': path.resolve(__dirname, 'src/apis'), | ||
'@assets': path.resolve(__dirname, 'src/assets'), | ||
'@hooks': path.resolve(__dirname, 'src/hooks'), | ||
'@pages': path.resolve(__dirname, 'src/pages'), | ||
'@store': path.resolve(__dirname, 'src/store'), | ||
'@utils': path.resolve(__dirname, 'src/utils'), | ||
}, | ||
}, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
요건 회사에 속한 팀 문화마다 다를 거 같아요. Web Vitals에 있는 수치를 중요시 여긴다면 CI 과정에서 특정 점수 이하로 내려가지 않도록 추적해서 내려간다면 CI를 깨뜨린다거나 PR 병합을 하지 못하게 한다거나 강하게 규칙을 적용할 수도 있을 거 같구요. 제가 속한 조직에서는 강한 규칙보다는 도구를 활용해서 각 수치가 얼만큼 변화하고 있는지 추적해서 대응하는 방향으로 처리하고 있어요. datadog 또는 sentry 와 같은 도구의 피처가 그 예시입니다.
제가 느끼기에는 일반적으로 아래처럼 3가지 단계를 반복적으로 진행하게 되는데요, 이를 위해 수치적 분석을 위한 개념을 이해하고 분석 및 개선 후 수치 변화 추적을 위해 Web Vitals, Lighthouse, Chrome DevTools의 Performance 탭 사용 방식을 익히는 것 정도가 생각나네요.
아래 3가지를 읽고 이해하는게 시작점이 될 수 있지 않나 싶습니다.