diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index cfa7845..0000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,27 +0,0 @@ - - - -## ✨ 구현 기능 명세 - -- 기본 과제 -- 심화 과제 -- 생각 과제 - -
- -## 🌼 PR Point - -- ~ 부분 이렇게 구현했어요, 피드백 부탁해요! - -
- -## 🥺 소요 시간, 어려웠던 점 - -- `6h` -- ~ 부분에서 이래서 시간을 얼만큼 썼어요.. - -
- -## 🌈 구현 결과물 - - \ No newline at end of file diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml deleted file mode 100644 index 7f226b3..0000000 --- a/.github/workflows/static.yml +++ /dev/null @@ -1,47 +0,0 @@ -# Simple workflow for deploying static content to GitHub Pages -name: Deploy static content to Pages - -on: - # Runs on pushes targeting the default branch - push: - branches: ['week3/assign1'] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write - -# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. -# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. -concurrency: - group: "pages" - cancel-in-progress: false - -jobs: - # Single deploy job since we're just deploying - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - defaults: - run: - working-directory: 'week3/Assignment1' - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Setup Pages - uses: actions/configure-pages@v3 - - name: Upload artifact - uses: actions/upload-pages-artifact@v1 - with: - # Upload entire repository - path: './dist' - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v2 diff --git a/week1/Assignment3/assets/2soon.jpeg b/week1/Assignment3/assets/2soon.jpeg deleted file mode 100644 index e5a088d..0000000 Binary files a/week1/Assignment3/assets/2soon.jpeg and /dev/null differ diff --git a/week1/Assignment3/assets/alright.jpeg b/week1/Assignment3/assets/alright.jpeg deleted file mode 100644 index 564679f..0000000 Binary files a/week1/Assignment3/assets/alright.jpeg and /dev/null differ diff --git a/week1/Assignment3/assets/blue.png.jpeg b/week1/Assignment3/assets/blue.png.jpeg deleted file mode 100644 index 6d9f8aa..0000000 Binary files a/week1/Assignment3/assets/blue.png.jpeg and /dev/null differ diff --git a/week1/Assignment3/assets/it's you.jpeg b/week1/Assignment3/assets/it's you.jpeg deleted file mode 100644 index 1979730..0000000 Binary files a/week1/Assignment3/assets/it's you.jpeg and /dev/null differ diff --git a/week1/Assignment3/assets/less of you.jpg b/week1/Assignment3/assets/less of you.jpg deleted file mode 100644 index 1b28525..0000000 Binary files a/week1/Assignment3/assets/less of you.jpg and /dev/null differ diff --git a/week1/Assignment3/assets/more.jpeg b/week1/Assignment3/assets/more.jpeg deleted file mode 100644 index f5703e3..0000000 Binary files a/week1/Assignment3/assets/more.jpeg and /dev/null differ diff --git a/week1/Assignment3/assets/summer.jpeg b/week1/Assignment3/assets/summer.jpeg deleted file mode 100644 index bec08ce..0000000 Binary files a/week1/Assignment3/assets/summer.jpeg and /dev/null differ diff --git a/week1/Assignment3/assets/the reaper.jpeg b/week1/Assignment3/assets/the reaper.jpeg deleted file mode 100644 index eed0cad..0000000 Binary files a/week1/Assignment3/assets/the reaper.jpeg and /dev/null differ diff --git a/week1/Assignment3/assets/touch.jpeg b/week1/Assignment3/assets/touch.jpeg deleted file mode 100644 index f661d8a..0000000 Binary files a/week1/Assignment3/assets/touch.jpeg and /dev/null differ diff --git a/week1/Assignment3/assets/us.jpeg b/week1/Assignment3/assets/us.jpeg deleted file mode 100644 index 60f87e9..0000000 Binary files a/week1/Assignment3/assets/us.jpeg and /dev/null differ diff --git a/week1/Assignment3/assets/xoxosos.jpeg b/week1/Assignment3/assets/xoxosos.jpeg deleted file mode 100644 index db07cc1..0000000 Binary files a/week1/Assignment3/assets/xoxosos.jpeg and /dev/null differ diff --git a/week1/Assignment3/index.html b/week1/Assignment3/index.html deleted file mode 100644 index e8459fe..0000000 --- a/week1/Assignment3/index.html +++ /dev/null @@ -1,169 +0,0 @@ - - - - - - - - - - - - - Keshi's Song - - -
-

🎶 keshi's song 🎶

- menu - -
- - - diff --git a/week1/Assignment3/style.css b/week1/Assignment3/style.css deleted file mode 100644 index 6c65e90..0000000 --- a/week1/Assignment3/style.css +++ /dev/null @@ -1,176 +0,0 @@ -/* GLOBAL */ -@font-face { - font-family: 'omyu'; - src: url('../font/오뮤_다예쁨체.ttf'); - font-weight: normal; -} -* { - margin: 0; - padding: 0; - font-family: "omyu", sans-serif; -} -body { - background-color: #00203f; - z-index: 1; -} - -/* HAEDER */ -header { - top: 0; - width: 100vw; - height: 100px; - background-color: #adefd1; - position: fixed; - display: flex; - align-items: center; - justify-content: space-between; -} -header h1 { - margin-left: 20px; - font-weight: 800; -} -header .material-symbols-outlined { - margin-right: 20px; - transform: scale(1.3); - cursor: pointer; -} -header .material-symbols-outlined:hover ~ aside, aside:hover { - display: flex; -} - -/* MENU ASIDE */ -aside { - width: 250px; - height: 100vh; - top: 0; - right: 0; - padding: 40px 0 0 20px; - position: fixed; - display: none; - flex-direction: column; - z-index: 999; - background-color: white; -} -aside h1 { - color: #68dca7; - margin-bottom: 80px; - font-size: 40px; -} -aside #menu_wrapper { - display: flex; - flex-direction: column; - gap: 20px; -} -aside #menu_wrapper span { - color: #68dca7; - line-height: 30px; - font-size: 35px; -} -aside #menu_wrapper span::after { - content: ""; - display: block; - width: 90%; - height: 2px; - margin-top: 15px; - background-color: #80808060; -} -aside #menu_wrapper span:hover { - color: #0db56a; -} - -/* MAIN */ -#nav_section_wrapper { - margin-top: 100px; - display: flex; -} - -/* NAV */ -nav #type_wrapper { - width: 200px; - margin: 10px 0 0 10px; - padding: 15px; - border-radius: 20px; - background-color: #68dca7; - display: flex; - flex-direction: column; - gap: 10px; -} -nav #type_wrapper article { - display: flex; - align-items: center; - height: 30px; - background-color: whitesmoke; - padding: 5px; - border-radius: 10px; -} -nav #type_wrapper article:hover { - color: #68dca7; - background-color: black; -} -nav #type_wrapper article input { - margin-right: 5px; -} - -/* CARD SECTION */ -#card_section { - margin: 10px 10px 0 20px; - width: 100%; - display: flex; - justify-content: flex-start; - flex-wrap: wrap; - gap: 20px; -} -#card_section article { - width: fit-content; - height: 300px; - min-width: 200px; - border-radius: 20px; - background-color: #adefd1; - display: flex; - flex-direction: column; - align-items: center; - flex-basis: 1; -} -#card_section article h2 { - margin-top: 10px; -} -#card_section article .tag_wrapper { - width: 160px; - height: 20px; - margin-bottom: 20px; - display: flex; - justify-content: center; - gap: 5px; - margin-bottom: 20px; - flex-wrap: wrap; - overflow-y: hidden; -} -#card_section article .tag_wrapper span { - font-size: 15px; - color: gray; -} -#card_section article .tag_wrapper span::before { - content: "#"; -} -#card_section article img { - max-width: 80%; - max-height: 60%; - background-color: black; -} -#card_section article .material-symbols-outlined { - color: #29dd8c; - margin: 20px 20px 0 0; - align-self: flex-end; - cursor: pointer; -} -#card_section article .material-symbols-outlined:hover { - color: black; -} -@media (max-width: 689px) { - #card_section { - justify-content: center; - } - #card_section article { - width: 60% - } -} \ No newline at end of file diff --git a/week1/Assignment4/index.html b/week1/Assignment4/index.html deleted file mode 100644 index db0e2d5..0000000 --- a/week1/Assignment4/index.html +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - - - - Todomate - - - -
-

WEB TO DO MATE

-
-
-
- - - - - - - -
- - favorite - 6 - -
-
- - favorite - 6 - -
-
- - favorite - 6 - -
-
- - favorite - 6 - -
-
- - favorite - 9 - -
-
- - favorite - 6 - -
-
- - favorite - 6 - -
-
27
-
28
-
29
-
30
-
31
-
1
-
2
-
-
-
-

- Hyeonggeun - add_circle -

-
-

- favorite - 베이킹 냠냠 -

-

- favorite - 방정리 -

-
-
-
-

- SOPT - add_circle -

-
-

- favorite - 웹팟 첫 세미나 -

-

- favorite - 웹팟 첫 뒷풀이 -

-

- favorite - 웹팟 워크샵 -

-
-
-
-

- 세종대 - add_circle -

-
-

- favorite - 캡스톤 발표 -

-

- favorite - UX / UI 디자인 -

-
-
-
-

- 운동 - add_circle -

-
-

- favorite - 솝케팟 번개 -

-

- favorite - 요가 -

-
-
-
-
- - - diff --git a/week1/Assignment4/style.css b/week1/Assignment4/style.css deleted file mode 100644 index 2614006..0000000 --- a/week1/Assignment4/style.css +++ /dev/null @@ -1,145 +0,0 @@ -/* GLOBAL */ -@font-face { - font-family: 'omyu'; - src: url('../font/오뮤_다예쁨체.ttf'); - font-weight: normal; -} -* { - margin: 0; - padding: 0; - font-family: "omyu", sans-serif; -} -body { - height: 100vh; - background-color: #c295d8; - z-index: 1; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; -} - -/* HEADER */ -header { - height: 10vh; - display: flex; - justify-content: center; - align-items: center; -} -header h1 { - margin-top: 20px; - color: white; - font-size: 40px; - text-shadow: 5px 5px 6px lightpink; -} - -/* MAIN */ -main { - margin-top: 30px; - height: calc(80vh - 30px); -} - -/* CALENDAR */ -#calendar { - width: 80vw; - height: 100px; - padding: 10px; - background-color: white; - box-shadow: 5px 5px 3px lightpink; - border-radius: 10px; - display: grid; - grid-template-columns: 11vw 11vw 11vw 11vw 11vw 11vw 11vw; - justify-content: center; - justify-items: center; - align-items: center; -} -#calendar article .material-symbols-outlined { - position: relative; -} -#calendar article .material-symbols-outlined span { - font-size: 8px; - color: white; - position: absolute; - left: 9px; - top: 6px; -} -#calendar .today { - color: #c295d8; -} - -/* TODO */ -#todo { - height: calc(80vh - 200px);; - margin-top: 30px; - display: flex; - flex-flow: column wrap; - gap: 10px; -} -#todo article { - width: fit-content; -} -#todo article h1 { - display: inline-flex; - font-size: 1rem; - color: #c295d8; - background-color: blanchedalmond; - padding: 10px 20px 10px 20px; - border-radius: 20px; - box-shadow: 5px 5px 3px lightpink; - gap: 5px; -} -#todo article h1 .material-symbols-outlined { - font-size: 1rem; -} -#todo article h1.sopt { - background-color: rgb(255, 212, 195); -} -#todo article h1.univ { - background-color: rgb(186, 219, 247); -} -#todo article h1.workOut { - background-color: rgb(189, 247, 221); -} -#todo article .todos_wrapper { - margin-top: 10px; - padding-left: 20px; - display: flex; - flex-direction: column; - align-items: flex-start; - gap: 3px; -} -#todo article .todos_wrapper p { - display: flex; - font-size: 0.8rem; - font-weight: 700; - align-items: center; - gap: 5px; -} -#todo article .todos_wrapper p .material-symbols-outlined { - color:#f2e4f9; - transform: scale(0.8); -} -#todo article .todos_wrapper p .material-symbols-outlined.checked { - color: #ef9776; -} - -/* FOOTER */ -footer { - height: 15vh; - display: flex; - flex-direction: row; - justify-content: center; - gap: 10px; -} -footer article { - width: 70px; - height: 80px; - border-radius: 10px; - color: #c295d8; - background-color: blanchedalmond; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - box-shadow: 3px 3px 6px lightpink; -} \ No newline at end of file diff --git a/week1/README.md b/week1/README.md deleted file mode 100644 index d8d649d..0000000 --- a/week1/README.md +++ /dev/null @@ -1,13 +0,0 @@ -![웹파트-오형근](https://user-images.githubusercontent.com/79238676/227774852-42882d62-bc9b-4eb1-a060-6d3033989a36.png) - - 해삐 웹팟에 오신 것을 환영합니다🌼 - -
- - | 주차 | 과제 내용 | 🔗 링크 | -| ----- | --------------------- | ------- | -| 1주차 | Keshi's songs | [링크](https://geun-oh.github.io/geunoh.github.io/week1/Assignment3/)| -| 1주차 | Todo mate |[링크](https://geun-oh.github.io/geunoh.github.io/week1/Assignment4/)| -| 1주차 | 📚 Web Optimization | [링크](https://github.com/GO-SOPT-WEB/HyeongGeunOh/blob/week1/week1/%EC%83%9D%EA%B0%81%EA%B3%BC%EC%A0%9C.md)| - -
diff --git "a/week1/font/\354\230\244\353\256\244_\353\213\244\354\230\210\354\201\250\354\262\264.ttf" "b/week1/font/\354\230\244\353\256\244_\353\213\244\354\230\210\354\201\250\354\262\264.ttf" deleted file mode 100644 index b26b9e9..0000000 Binary files "a/week1/font/\354\230\244\353\256\244_\353\213\244\354\230\210\354\201\250\354\262\264.ttf" and /dev/null differ diff --git "a/week1/\354\203\235\352\260\201\352\263\274\354\240\234.md" "b/week1/\354\203\235\352\260\201\352\263\274\354\240\234.md" deleted file mode 100644 index e7c61b7..0000000 --- "a/week1/\354\203\235\352\260\201\352\263\274\354\240\234.md" +++ /dev/null @@ -1,111 +0,0 @@ -## 1주차 생각과제 - -
-
- -## 웹 최적화는 무었일까? - -웹에 접속하는 사람 마다의 네트워크 상황이 다를 수 있고, 웹 서비스별로 목표로 하는 사용자나 평균 접속자 수가 상이할 수 있기 때문에 -이러한 여러 상황들을 고려하여 서비스를 제공하는데 필요한 렌더링에 걸리는 시간을 줄이는 것! - -
-
- -## 최적화가 필요한 이유는 무엇일까? - -네트워크가 원활하지 못한 사용자나 상황에서도 서비스를 이용할 수 있도록 하여 범용성을 넓히기 위해서 필요하고, -사용 환경을 고려하지 않더라도 더 좋은 사용자 경험 제공을 위해 필수적으로 따져야 한다. -좋은 사용자 경험은 사용자들의 서비스 재방문 여부를 결정하는 중요한 지표이므로 렌더링 최적화를 신경써야할 필요가 있다! - -
-
- -## 이를 위해 어떤 개발을 해야할까? - -브라우저에 서비스가 렌더링되는 방법을 고려하여 렌더링 최적화를 진행하거나, -서비스 번들 크기 자체를 줄여 웹 서버에서 번들 파일을 제공하는 시간을 단축하거나, -서버에서 데이터를 불러올 때 캐싱 등의 방법을 적용하여 불필요한 작업들을 최소화한다! - -렌더링 최적화를 위한 수단으로는 여러가지가 있겠지만, -대표적으로는 아래의 수단들이 있습니다. - -
- -### 1. 번들러 사용하기 - -Webpack, Vite, Bun 등의 자바스크립트 번들러는 우리가 작성한 코드를 하나로 묶어 압축하여 큰 파일로 만들어주는데, 이 과정에서 불필요한 공백들을 없애는 등의 최적화 과정을 거칩니다. 이를 통해 결과적으로 웹 서버에 저장되는 파일의 크기를 효과적으로 줄여줌으로서 렌더링 최적화를 진행할 수 있습니다. - -
- -### 2. 라이브러리 의존도 줄이기 - -간단한 기능을 구현하기 위해 모두 라이브러리를 불러와 사용하다 보면 최종 번들 크기가 커지고 최적화에 큰 영향을 줄 수 있습니다. -이를 발지하기 위해 핵심 기능 구현을 위해 필수적인 라이브러리들을 제외하고 불필요하거나 직접 구현할 수 있는 기능들은 -직접 구현해보는 것이 좋다고 생각합니다. - -
- -### 3. 개발 의존성 라이브러리 구별하기 - -필수적인 라이브러리 중에서도 개발 단계에서만 사용해도 되는 라이브러리와 실제 서비스 단에서 사용되는 라이브러리가 있습니다. -이를 구별하여 package.json에 명시해주는 것이 최종 번들 크기를 줄이는 효과적인 방법이 된다고 생각합니다. - -
- -### 4. 캐싱 - -캐싱은 서비스에서 데이터 변경 시 발생하는 리렌더링이나 데이터 패칭의 과정을 최적화하기 위해 사용됩니다. -기존의 렌더링된 사항에서 변경사항이 없음을 감지한 부분은 다시 그리지 않음으로써 로딩 시간을 단축할 수 있고, -데이터를 불러오는 과정 또한 캐싱을 통해 동일한 데이터에 대한 불필요한 재호출을 막음으로써 로딩 시간을 단축할 수 있습니다. - -캐싱을 위해 사용되는 것들로는 React의 useMemo, useCallback 훅, React query / SWR 라이브러리 등이 있습니다!! - -
- -### 5. 이미지 최적화(Lazy loading, img sprite), 폰트 최적화 - -이미지는 텍스트보다 용량이 크기 때문에 웹에서 렌더링을 신경써야 하는 주된 요소 중 하나입니다. -이때 화면에 들어오는 이미지만 동적으로 로딩하는 지연 로딩(Lazy loading)을 적용하거나, -아이콘과 같이 간단하지만 자주 사용되는 이미지들은 하나의 이미지로 묶어 위치정보를 통해 해당 아이콘을 구현하는 이미지 스프라이트를 적용해도 좋습니다. - -폰트 파일 또한 번들 크기에 영향을 크게 주는 요소 중 하나입니다. -폰트 파일은 크기가 매우 크므로 폰트를 외부에서 불러오는 방식을 적용하거나, 압축된 폰트 확장자(WOFF, WOFF2)를 적용한다거나, -서브셋 폰트 사용등을 통해 폰트 최적화를 진행할 수 있습니다. - -
- -### 6. 상황에 맞는 렌더링 기법 적용하기 - -브라우저에 파일을 렌더링하는 방법은 크게 네 가지가 대표적으로 있습니다. - -`CSR`: 클라이언트에서 직접 사이트를 렌더링하고, 데이터 패칭, 라우팅 등의 모든 작업을 클라이언트에서 진행하는 기법입니다. -일반적으로 동적인 페이지 생성에 가장 많이 사용됩니다. - -`SSR`: 서버 사이드에서 사이트를 미리 생성하고 이를 클라이언트에 보내 띄우는 방식으롸, 초기 로딩 시간이 CSR에 비해 짧다는 장점이 있어 -초기 페이지 로딩 시 UX 개선에 효과적입니다. 또한 서버에서 미리 페이지를 렌더링하므로, SEO에 효과적입니다. -그러나 매 페이지 이동마다 새로운 리소스를 다운받아 페이지 렌더링을 해야하므로 CSR보다 페이지 이동이 원활하지 못함. - -`SSG`: 서버에서 미리 렌더링된 사이트를 전달해주므로 로딩이 빠르고, SEO에 적합하다. -대신 동적인 컨텐츠 제공이 어렵다. -데이터의 변경이 잦지 않은 블로그 등의 정적 페이지에 적합합니다. - -`ISR`: SSG를 일정 시간마다 재수행하는 렌더링 기법이라고 생각하면 좋다. -정적인 페이지를 렌더링하되, 일정 주기를 기준으로 데이터를 다시 불러 새로운 페이지를 렌더링해줍니다. - -
- -### 7. 성능 최적화 도구 적용하기 - -실제 내가 적용한 방법들이 잘 적용되어 좋은 효과를 내는지 확인하기 위해 Chrome lighthouse와 같은 툴을 이용하여 렌더링 최적화 정도를 파악할 수 있다. - - -
-
- -### 최적화를 위한 개발을 꼭 해야할까? - -필수적이라고 할 수는 없더라도, 서비스의 범용성을 생각한다면 꼭 필요한 과정이라고 생각합니다. -최적화를 진행한 결과물과 진행하지 않은 결과물을 비교하였을 때 그 차이를 쉽게 느낄 수 있습니다. - -최적화 과정은 메인 비즈니스 로직과는 별개의 영역이지만, -서비스의 고도화는 유저의 이탈을 효과적으로 막고, 동일한 서비스를 제공하는 경쟁사와의 경쟁에서 아이덴티티를 확보하고 유저를 잡아두기 위한 서비스 고도화에 필수적인 과정이라고 생각합니다. diff --git "a/week3/\354\203\235\352\260\201\352\263\274\354\240\234.md" "b/week3/\354\203\235\352\260\201\352\263\274\354\240\234.md" new file mode 100644 index 0000000..46513cb --- /dev/null +++ "b/week3/\354\203\235\352\260\201\352\263\274\354\240\234.md" @@ -0,0 +1,30 @@ +## 💟 React에서 상태관리는 왜 필요한가? + + - 상태(state) 란 세미나 때 공부한 것처럼 컴포넌트 내부에서 공유되는 지역 변수와도 같다. 일반적으로 선언된 변수와 다른 점이라면 데이터 바인딩이 적용되어 JSX 문법과 사용하기 좋다는 것이고, 동적인 데이터를 다루기 용이하다는 점이다. + + - 상태를 사용하여 동적인 웹 페이지를 생성하는 과정에서 상태관리는 필수가 되었다. 리액트 프로젝트의 규모가 커지고 코드 추상화에 따른 파일과 폴더의 수가 증가할수록 컴포넌트 간의 데이터를 전달하고 특정 컴포넌트에서의 상태 변경을 이에 관여하는 모든 컴포넌트들에 전달하기 어려워지는 문제가 발생했다. 이러한 개별 컴포넌트 관계를 정확하게 파악하고 데이터를 전달해주기 어려운 상황에서 우리는 각 컴포넌트에서 사용하는 상태를 관리하고, 특히 컴포넌트 간에 공유되는 상태를 관리할 필요가 생긴 것이다. + + - 이러한 상황에서 등장한 것이 '전역 상태 관리'라는 개념인데, 기존에 props drilling으로 해결하던 컴포넌트 간의 상태 전달 문제를 전역적으로 관리해야하는 상태를 따로 빼낸 store의 개념을 도입하며 해소하였다. 다수의 컴포넌트에 공유되는 상태를 전역 상태로 선언하여 관리에 용이하게 만든 것이다. + +### 관리 해야 하는 상태에 대한 기준은 무엇인가? + +- 상태관리가 필요한 상태의 경우 여러 컴포넌트에서 공유되는 값을 가지고 있다는 특징이 있다. 여러 컴포넌트에서 해당 값을 사용해야하므로, 이를 전역 상태 관리 store 단에서 선언해 값을 사용하고자 하는 모든 컴포넌트에 전달할 필요가 있다. + +### 어떤 상태관리 라이브러리를 어떤 상황에서 사용해야 할까? + +- 상태 관리 라이브러리는 Redux, Recoil, ContextAPI 등등이 존재하는데, 나는 우선 이 3가지를 비교해보고자 한다. 우선 ContextAPI 는 React 내장 기능으로 그 목적이 나머지 둘과 조금 다르다. 상태 관리를 위한 것은 맞지만 전역상태관리에 목적을 두는 것은 아니다. 오히려 Redux, Recoil이 전역상태관리를 위한 다양한 기능들을 많이 제공해주므로 전역 상태관리를 위해서라면 Redux, Recoil 등의 라이브러리를 사용하는 것이 좋다. ContextAPI는 그 외에 간단한 컴포넌트 묶음 내부에서 공유할 상태가 존재하는 경우 등 특수한 상황에서 가볍게 적용하는 것이 좋다고 생각했다. + +- Redux와 Recoil을 비교하면, Redux는 오랫동안 유명했고 그만큼 사용자와 팬층이 두터워 현재 분명한 1위로 자리하고 있다. 또한 강력한 Devtools와 Flux 패턴 기반의 아키텍쳐는 Redux를 사용하는 개발자들의 개발자 경험을 충분히 끌어올려준다. 그러나 React 친화적이고 Redux보다 훨씬 간단한 구성 환경을 제공하여 진입장벽을 낮춘 Recoil의 경우 앞으로 사용자가 많이 늘어나고 적용하는 곳이 많아진다면 충분히 입지를 다질 수 있을 것이라고 생각한다. 그리고 Recoil 또한 Devtools가 발전 중에 있고, React를 만든 페이스북에서 React를 위한 상태관리 라이브러리라고 소개한 만큼 시간이 지나면 React 생태계 내에서 충분히 Redux와 견줄 만한 좋은 라이브러리가 될 수 있을 것이라고 생각한다. + +- 따라서 정말 대규모 비즈니스 로직을 관리하는 곳에서는 Redux를 사용하고, 아직 대규모가 아니거나 프로젝트 단위의 개발이라면 충분히 Recoil을 사용해도 좋을 것 같다. + +## 💟 React에서 렌더링을 효과적으로 관리하는 방법은 무엇이 있을까? + +- React에서 렌더링은 사용자 경험을 좌지우지하는 결정적인 요소이다. 렌더링을 효과적으로 관리하기 위해서는 불필요한 리렌더링을 방지하는 것이 가장 중요하다. 불필요한 리렌더링이란 특정 state의 변경을 감지하고 리렌더링을 진행할 때, 해당 state의 변경에 영향을 받지 않는 요소까지 렌더링되는 것을 말한다. 이를 위해서는 useMemo 혹은 useCallback과 같은 메모이제이션을 위한 훅을 사용하면 좋다. + + +### 이를 위해 어떤 식으로 비즈니스 설계를 진행해야 할까 + +- state가 변경되는 로직을 캡슐화하여 관리하는 방법이 존재한다. 뷰와 로직을 분리하고 로직을 따로 관리함으로써 해당 state에 영향을 받는 것들을 확실하게 할 수 있다. + +- 이를 위해 이전에 언급되었던 Custom Hooks를 최대한 활용하면 좋을 것 같다.