Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ssi02014/gachigayo_front_template

๐Ÿ›ฌ ๊ฐ€์น˜๊ฐ€์š” ํŒ€ํ”„๋กœ์ ํŠธ ํ”„๋ก ํŠธ์—”๋“œ ํ…œํ”Œ๋ฆฟ
https://github.com/ssi02014/gachigayo_front_template

react redux redux-saga storybook styled-components

Last synced: 8 days ago
JSON representation

๐Ÿ›ฌ ๊ฐ€์น˜๊ฐ€์š” ํŒ€ํ”„๋กœ์ ํŠธ ํ”„๋ก ํŠธ์—”๋“œ ํ…œํ”Œ๋ฆฟ

Awesome Lists containing this project

README

        

# ๐Ÿ›ฌ ๊ฐ€์น˜๊ฐ€์š” ํ”„๋ก ํŠธ ํ…œํ”Œ๋ฆฟ ๋ฐ ์ฐธ๊ณ  ๋ฌธ์„œ

## ๐Ÿ“• ํ”„๋กœ์ ํŠธ ํ…œํ”Œ๋ฆฟ ํ–‰๋™ ์ˆ˜์น™

```
git clone https://github.com/ssi02014/gachigayo_front_template.git
```

1. ๋กœ์ปฌ์—๋‹ค ๊ฐ์ž ์ž‘์—… ํด๋”์— cloneํ•˜๊ธฐ

```
yarn
๋˜๋Š”
yarn install
```

2. ํŒจํ‚ค์ง€ ์˜์กด์„ฑ ์„ค์น˜ (๋ฐ‘์— ์„ค๋ช…ํ•˜๊ฒ ์ง€๋งŒ npm์œผ๋กœ๋„ ํŒจํ‚ค์ง€ ์„ค์น˜๊ฐ€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ํŒ€์› ๋ชจ๋‘ yarn์œผ๋กœ ํ†ต์ผ)


## ๐Ÿค™ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €(Yarn)

- ํŒจํ‚ค์ง€ ์„ค์น˜์™€ ๊ฐ™์€ ํŒจํ‚ค์ง€์™€ ๊ด€๋ จ๋œ ๋ชจ๋“  ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ๋Š” `yarn`์œผ๋กœ ํ†ต์ผ!
- [yarn ๊ณต์‹ ํ™ˆํŽ˜์ด์ง€](https://yarnpkg.com/)
- [yarn ์„ค์น˜ ์ฐธ๊ณ  ์‚ฌ์ดํŠธ](https://heropy.blog/2017/11/25/yarn/)
- [yarn vs npm ๋ช…๋ น์–ด](https://dongmin-jang.medium.com/npm-vs-yarn-7b699c5d6034)


### yarn์ด๋ž€?

- Facebook์—์„œ ๋งŒ๋“  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €
- npm๊ณผ yarn ๋ชจ๋‘ package.json์— ๋ฒ„์ „์„ ๋ช…์‹œํ•˜๊ณ  ์˜์กด์„ฑ์„ ์ถ”์  ๊ด€๋ฆฌํ•˜๋Š” ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €์ด๋‹ค. ํ•˜์ง€๋งŒ ํ˜น์‹œ ๋ชจ๋ฅผ ํŒจํ‚ค์ง€ ๊ด€๋ จ ์ด์Šˆ์— ๋Œ€๋น„ํ•ด ๋ชจ๋“  ํŒ€์›์€ `yarn`์œผ๋กœ ํ†ต์ผํ•œ๋‹ค.


### npm๊ณผ yarn์˜ ์ฐจ์ด

- ์—ฌ๋Ÿฌ ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•  ๋•Œ npm์€ ์ˆœ์ฐจ์ ์œผ๋กœ ์„ค์น˜๋˜๋Š” ๋ฐ˜๋ฉด, yarn์€ `๋ณ‘๋ ฌ`๋กœ ์ฒ˜๋ฆฌ๋ผ ์„ค์น˜ ์‹œ๊ฐ„ ๋‹จ์ถ•๋œ๋‹ค.
- yarn์€ npm๊ณผ ๋‹ฌ๋ฆฌ ํŒจํ‚ค์ง€๋ฅผ ์ค‘๋ณต์œผ๋กœ ์„ค์น˜ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์—†๋‹ค.
- npm์€ ๋‹ค๋ฅธ ํŒจํ‚ค์ง€๋ฅผ ์ฆ‰์‹œ ํฌํ•จ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ์ž๋™์œผ๋กœ ์‹คํ–‰ํ•˜๋ฏ€๋กœ, ๋ณด์•ˆ ์‹œ์Šคํ…œ์— ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ทจ์•ฝ์„ฑ ๋ฐœ์ƒํ•œ๋‹ค. ๋ฐ˜๋ฉด yarn์€ yarn.lock ๋˜๋Š” package.json ํŒŒ์ผ์— ์žˆ๋Š” ํŒŒ์ผ๋งŒ ์„ค์น˜ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ Yarn์ด npm๋ณด๋‹ค ๋ณด์•ˆ์ด ๊ฐ•ํ•˜๋‹ค.


## ๐Ÿ“• ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

![image](https://user-images.githubusercontent.com/64779472/147206751-111019ec-3baf-44a2-9b39-ce7ac9681e9f.png)

### (์ฐธ๊ณ ) ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ๋Š” ํ”„๋กœ์ ํŠธ ์ง„ํ–‰ ์ค‘์— ์ถ”๊ฐ€/์ˆ˜์ • ๋  ์ˆ˜ ์žˆ์Œ.

- .storybook: ์Šคํ† ๋ฆฌ๋ถ ์…‹ํŒ… ๊ด€๋ จ ํด๋”
- api: api ๊ด€๋ จ ํด๋”
- components: ์ปดํฌ๋„ŒํŠธ ๊ด€๋ จ ํด๋”
- config: colorSystem ๊ฐ™์€ ํ”„๋กœ์ ํŠธ ๊ตฌ์„ฑ ๊ด€๋ จ ํด๋”
- hooks: ์ปค์Šคํ…€ ํ›… ๊ด€๋ จ ํด๋”
- redux: ๋ฆฌ๋•์Šค ๊ด€๋ จ ํด๋”
- static: ์ •์  ํŒŒ์ผ(์ด๋ฏธ์ง€, ๊ธ€๋กœ๋ฒŒ style ๋“ฑ) ๊ด€๋ จ ํด๋”
- stories: ์Šคํ† ๋ฆฌ๋ถ ๊ด€๋ จ ํด๋”
- utils: ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ด€๋ จ ํด๋”


## ๐Ÿ“• ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ ๊ฐœ๋ฐœ ๋ฐฉ์‹

```js
// ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ
import React, { useState } from "react";

const Test = () => {
const [data, setData] = useState(0); // Hook์˜ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ์ธ useState
return

ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ ์˜ˆ์ œ
;
};

export default Test;
```

- ํ”„๋กœ์ ํŠธ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ ๊ฐœ๋ฐœ ๋ฐฉ์‹์€ `ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ`๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
- ์™œ? ๊ณผ๊ฑฐ์—๋Š” ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ–ˆ์ง€๋งŒ `2019๋…„ ๋ฆฌ์•กํŠธ v16.8` ๋ถ€ํ„ฐ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์— `๋ฆฌ์•กํŠธ ํ›…(Hook)`์„ ์ง€์›ํ•ด ์ฃผ์–ด์„œ ํ˜„์žฌ๋Š” ๋ฆฌ์•กํŠธ ๊ณต์‹ ๋ฌธ์„œ์—์„œ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์™€ ํ›…์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ด์„œ ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•œ๋‹ค.
- ์ตœ๊ทผ์— ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ๋Š” ๋ ˆ๊ฑฐ์‹œ ์ฝ”๋“œ๋“ค์ด ๋งŽ๋‹ค.
- [ํ•จ์ˆ˜ํ˜• vs ํด๋ž˜์Šคํ˜• ์ฐธ๊ณ  ์ž๋ฃŒ](https://velog.io/@sdc337dc/0.%ED%81%B4%EB%9E%98%EC%8A%A4%ED%98%95-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8)


## ๐Ÿ“• Design Pattern (Container & Presentational)

- Container - Presentational ๋””์ž์ธ ํŒจํ„ด์˜ ํ•ต์‹ฌ์€ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ์™€ ๋ฐ์ดํ„ฐ ์ถœ๋ ฅ์„ ๋ถ„๋ฆฌํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
- Container: `์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€, ์–ด๋–ค ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•˜๋Š”์ง€์— ๊ด€๋ จ์žˆ๋‹ค.` ์ƒํƒœ, ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๋“ค์„ ๋ชจ์•„ ๋†“๋Š”๋‹ค. markup, style์„ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ๋œ๋‹ค.
- Presentational: Container์—์„œ ์ฒ˜๋ฆฌํ•œ ์ƒํƒœ๋ฅผ props๋กœ ์ „๋‹ฌ๋ฐ›์•„ ์ƒํƒœ๋ฅผ ํ™”๋ฉด์— ์ถœ๋ ฅํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ.


### ๋””์ž์ธ ํŒจํ„ด ์ ์šฉ ์‹œ ์žฅ์ 

1. ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ ์ฆ๊ฐ€
2. ์žฌ์‚ฌ์šฉ์„ฑ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค.


### ์˜ˆ์ œ

- Container

```tsx
const CounterPage = () => {
const dispatch = useDispatch();
const count = useSelector((state: RootState) => state.counter.count);

const onIncrease = useCallback((e: React.MouseEvent) => {
e.preventDefault();

dispatch(counterIncrease());
}, []);

const onDecrease = useCallback((e: React.MouseEvent) => {
e.preventDefault();

dispatch(counterDecrease());
}, []);

const onClear = useCallback((e: React.MouseEvent) => {
e.preventDefault();

dispatch(counterClear());
}, []);

return (
<>

>
);
};
```

- Presentational

```tsx
interface Props {
count: number;
onIncrease: (e: React.MouseEvent) => void;
onDecrease: (e: React.MouseEvent) => void;
onClear: (e: React.MouseEvent) => void;
}
const Counter = ({ count, onIncrease, onDecrease, onClear }: Props) => {
return (


์นด์šดํ„ฐ


์ฆ๊ฐ€
๊ฐ์†Œ
์ดˆ๊ธฐํ™”

{count}



);
};

export default Counter;
```


## ๐Ÿ“• ํ”„๋กœ์ ํŠธ ์ฐธ๊ณ ์‚ฌํ•ญ ๋ฐ ์ž๋ฃŒ

### โœจ 1. react-router-dom

- react-router-dom ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ตœ๊ทผ v6์œผ๋กœ ๋ฒ„์ „ ์—…๊ทธ๋ ˆ์ด๋“œ๋˜๋ฉด์„œ ๋งŽ์€ ๋ถ€๋ถ„์ด ๋ณ€ํ•จ.
- [Router v6 ์ฐธ๊ณ  ์ž๋ฃŒ](https://velog.io/@ksmfou98/React-Router-v6-%EC%97%85%EB%8D%B0%EC%9D%B4%ED%8A%B8-%EC%A0%95%EB%A6%AC)


### โœจ 2. ์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ…

- ์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ…(Code splitting) ๊ตฌํ˜„์„ ์œ„ํ•œ `loadable ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ` ์‚ฌ์šฉ

```
yarn add @loadable/component
yarn add @types/loadable__component -D

(๋’ค์— -D ๋ฅผ ๋ถ™์ธ ์ด์œ ๋Š” ๊ฐœ๋ฐœ๋ชจ๋“œ์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•จ)
```

- ์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ…์ด๋ž€, ์šฐ๋ฆฌ๊ฐ€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค๊ฒŒ๋˜๋ฉด, ๊ธฐ๋ณธ์ ์œผ๋กœ ํ•˜๋‚˜์˜ ํŒŒ์ผ์— ๋ชจ๋“  ๋กœ์ง๋“ค์ด ๋“ค์–ด๊ฐ€๊ฒŒ ๋œ๋‹ค. ๊ทธ๋Ÿผ, ํ”„๋กœ์ ํŠธ์˜ ๊ทœ๋ชจ๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ ์šฉ๋Ÿ‰๋„ ์ปค์ง€๊ฒŒ ๋œ๋‹ค. ์šฉ๋Ÿ‰์ด ์ปค์ง€๋ฉด ์ธํ„ฐ๋„ท์ด ๋Š๋ฆฐ ํ™˜๊ฒฝ์—์„œ๋Š” ํŽ˜์ด์ง€ ๋กœ๋”ฉ์ด ๋Š๋ ค์งˆ ๊ฒƒ์ด๋‹ค.
- ์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ…์„ ํ•˜๊ฒŒ ๋˜๋ฉด, ์ง€๊ทธ ๋‹น์žฅ ํ•„์š”ํ•œ ์ฝ”๋“œ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ๋ถ„๋ฆฌ์‹œ์ผœ์„œ ๋‚˜์ค‘์— ํ•„์š”ํ•  ๋•Œ ๋ถˆ๋Ÿฌ์™€์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, `ํŽ˜์ด์ง€์˜ ๋กœ๋”ฉ ์†๋„๋ฅผ ๊ฐœ์„ `ํ•  ์ˆ˜ ์žˆ๋‹ค.


### โœจ 3. craco๋ฅผ ์ด์šฉํ•œ ์ ˆ๋Œ€ ๊ฒฝ๋กœ

```
yarn add @craco/craco
yarn add craco-alias -D
```

- ํ”„๋กœ์ ํŠธ ํด๋” ๊ตฌ์กฐ๊ฐ€ ๊ฒน๊ฒน์ธ ๊ฒฝ์šฐ, import ๊ฒฝ๋กœ๋ฅผ ์ƒ๋Œ€ ๊ฒฝ๋กœ๋กœํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ๋„ˆ๋ฌด ๊ธธ์–ด์ง€๊ณ  ๋ณด๊ธฐ๊ฐ€ ์–ด๋ ต๋‹ค.
- ์ด๋Ÿด ๋•Œ tsconfig.json์— paths๋ฅผ ์„ค์ •ํ•ด์„œ ์ ˆ๋Œ€ ๊ฒฝ๋กœ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ yarn startํ•  ๋•Œ๋งˆ๋‹ค tsconfig.json์ด ์ดˆ๊ธฐํ™”๋˜๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•œ๋‹ค. ์ด๋Ÿด ๋•Œ eject๋ฅผ ํ•ด์„œ ์ˆจ๊ฒจ์ง„ webpack์˜ ์„ค์ •์„ ๋ฐ”๊ฟ”์•ผํ•˜๋Š”๋ฐ, ๊ทธ๋Ÿฌ๊ธฐ์—” ์†์ด ๋„ˆ๋ฌด ๋งŽ์ด ๊ฐ€๊ธฐ ๋•Œ๋ฌธ์— `craco ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ`๋ฅผ ์‚ฌ์šฉํ•ด ํŽธ๋ฆฌํ•˜๊ฒŒ webpack ์„ค์ •(Eslint, Babel, Postcss ๋“ฑ)์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค.
- [Craco๋ฅผ ์ด์šฉํ•œ ์ ˆ๋Œ€ ๊ฒฝ๋กœ ์ฐธ๊ณ  ์ž๋ฃŒ](https://www.howdy-mj.me/boilerplate/craco-absolute-paths-setting/)

```js
// ์ƒ๋Œ€ ๊ฒฝ๋กœ ์˜ˆ์‹œ
import Login from "../../../../../Login";

// ์ ˆ๋Œ€ ๊ฒฝ๋กœ ์˜ˆ์‹œ
import Login from "@components/Login";
```


### โœจ 4. Storybook

- Storybook์€ ๋‹ค์–‘ํ•œ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋Š” `UI ์ปดํฌ๋„ŒํŠธ ๋‹จ์œ„ ๊ฐœ๋ฐœ ๋„๊ตฌ`์ด๋‹ค.
- ํŽ˜์ง€์ด ๋‹จ์œ„์˜ ๊ฐœ๋ฐœ์ด ์ด๋ฃจ์–ด์ง€๋˜ ๊ณผ๊ฑฐ์™€๋‹ฌ๋ฆฌ ์š”์ฆ˜์˜ ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์€ ์ฃผ๋กœ ์ปดํฌ๋„ŒํŠธ ๋‹จ์œ„๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค.
- ์ปดํฌ๋„ŒํŠธ๋ผ๋Š” ๊ฐœ๋…์€ ์‚ฌ์šฉํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ ํ”„๋ ˆ์ž„์›Œํฌ์— ๋”ฐ๋ผ ๊ตฌํ˜„ ๋ฐฉ์‹์€ ๋‹ค๋ฅด์ง€๋งŒ, ์ฒ ํ•™์€ ๊ฑฐ์˜ ๋™์ผํ•˜๋‹ค. ์ปดํฌ๋„ŒํŠธ๋Š” ์™ธ๋ถ€ ์ƒํƒœ์˜ ์˜ํ–ฅ์„ ๋ฐ›์ง€์•Š๋Š” ๋…๋ฆฝ๋œ ๊ฐœ์ฒด๋กœ์„œ, ๊ณ ๋ฆฝ๋œ ํ™˜๊ฒฝ์—์„œ๋„ ์ž์‹ ๋งŒ์˜ ์Šคํƒ€์ผ๊ณผ ์ƒํƒœ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ๋˜ํ•œ, React์˜ ์ปดํฌ๋„ŒํŠธ ์ •์˜์— ๋”ฐ๋ฅด๋ฉด, ์ปดํฌ๋„ŒํŠธ๊ฐ€ UI๋ฅผ ๋…๋ฆฝ์ ์ด๊ณ  ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋‹จ์œ„๋กœ ๋ถ„๋ฆฌํ•˜๊ณ  ๊ฐ ๋‹จ์œ„์˜ ๊ณ ๋ฆฝํ•ด์„œ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค๊ณ  ์„ค๋ช…ํ•œ๋‹ค.
- Storybook์˜ ๊ธฐ๋ณธ ๊ตฌ์„ฑ ๋‹จ์œ„๋Š” `์Šคํ† ๋ฆฌ(Story)`์ด๋ฉฐ, Story๋Š” ํ•ด๋‹น UI ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ํ•˜๋‚˜์˜ ์˜ˆ์‹œ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ํŽธํ•˜๋‹ค.
- Storybook์„ ์‚ฌ์šฉํ•˜๋ฉด UI ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ฐ๊ฐ ๋…๋ฆฝ์ ์œผ๋กœ ์–ด๋–ป๊ฒŒ ์‹ค์ œ๋กœ ๋ Œ๋”๋ง๋˜๋Š”์ง€ ์ง์ ‘ ์‹œ๊ฐ์ ์œผ๋กœ ํ…Œ์ŠคํŠธํ•˜๋ฉด์„œ ๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
- ํ•ด๋‹น UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฐœ๋ฐœ์ž ์ž…์žฅ์—์„œ๋„ ์ฝ”๋“œ๋ฅผ ๋ณด์ง€ ์•Š๊ณ ๋„ ๋ฏธ๋ฆฌ ๊ฐ UI ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ฒดํ—˜ํ•ด๋ณด๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด ๋งค์šฐ ์œ ์šฉํ•˜๋‹ค.
- ๊ฒฐ๊ณผ์ ์œผ๋กœ, ๋…๋ฆฝ์ ์ธ ์ปดํฌ๋„ŒํŠธ ๋‹จ์œ„ ๊ฐœ๋ฐœ๊ณผ UI ํ…Œ์ŠคํŠธ๋•Œ ๋งŽ์ด ์‚ฌ์šฉํ•œ๋‹ค.
- [Storybook ๊ณต์‹ ์‚ฌ์ดํŠธ](https://storybook.js.org/)
- [Storybook ํŠœํ† ๋ฆฌ์–ผ](https://storybook.js.org/tutorials/intro-to-storybook/react/ko/get-started/)
- [Storybook ์ž…๋ฌธ ๊ฐ€์ด๋“œ](https://hyunseob.github.io/2018/01/08/storybook-beginners-guide/)


### โœจ 5. TypeScript Type Alias(ํƒ€์ž… ๋ณ„์นญ) vs interface(์ธํ„ฐํŽ˜์ด์Šค)

```ts
// type
type Student = {
name: string;
age: number;
};

const student: Student = {
name: "Minjae",
age: 27,
};
```

```ts
// interface
interface Student {
name: string;
age: number;
}

const student: Student = {
name: "Minjae",
age: 27,
};
```

- Type Alias์™€ Interfaces๋Š” ์„œ๋กœ ๋Œ€๋ถ€๋ถ„์˜ ๊ธฐ๋Šฅ์„ ๊ณต์œ ํ•˜๊ณ  ์žˆ๋‹ค.


### ์ฐจ์ด์ 

1. ํ™•์žฅ ์ƒ์† ๋ฐฉ๋ฒ•

```ts
// interface
interface Person {
name: string;
age: number;
}
interface Student extends Person {
University: string;
}

// type
type Person = {
name: string;
age: number;
};
type Student = Person & {
University: string;
};
```

- interface๋Š” `extends` ํ‚ค์›Œ๋“œ๋ฅผ ํ†ตํ•ด ํ™•์žฅ๋œ๋‹ค.
- Type Alias์˜ ๊ฒฝ์šฐ `& (intersection Type)`๋ฅผ ์ด์šฉํ•œ๋‹ค.


2. ํƒ€์ž… ์ง€์ • ๋ฒ”์œ„

```ts
type Str = "Lee";

// ์œ ๋‹ˆ์˜จ ํƒ€์ž…์œผ๋กœ ํƒ€์ž… ์ง€์ •
type Union = string | null;

// ํ•จ์ˆ˜ ์œ ๋‹ˆ์˜จ ํƒ€์ž…์œผ๋กœ ํƒ€์ž… ์ง€์ •
type Func = (() => string) | (() => void);

// ์ธํ„ฐํŽ˜์ด์Šค ์œ ๋‹ˆ์˜จ ํƒ€์ž…์œผ๋กœ ํƒ€์ž… ์ง€์ •
type Shape = Square | Rectangle | Circle;

// ํŠœํ”Œ๋กœ ํƒ€์ž… ์ง€์ •
type Tuple = [string, boolean];
```

- interface๋Š” ํƒ€์ž…๋งŒ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ Type Alias๋Š” ์›์‹œ๊ฐ’์ด๋‚˜ ์œ ๋‹ˆ์˜จ ํƒ€์ž…, ํŠœํ”Œ ๋“ฑ๋„ ํƒ€์ž…์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.


3. ์„ ์–ธ์  ํ™•์žฅ(Declaration Merging), ์ž๋™ ํ™•์žฅ

```ts
interface Person {
name: string;
age: number;
}
interface Person {
gender: string;
}
```

- interface์˜ ๊ฒฝ์šฐ ๋™์ผํ•œ ์ด๋ฆ„์˜ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์ƒ์„ฑ๋˜๋ฉด ์ž๋™์ ์œผ๋กœ ํ™•์žฅ์ด ์ด๋ฃจ์–ด์ง€์ง€๋งŒ Type Alias๋Š” ํ™•์žฅ๋˜์ง€ ์•Š๋Š”๋‹ค.


### ๊ฒฐ๋ก 

- ํ”„๋กœ์ ํŠธ ๋‚ด์—์„œ union์ด๋‚˜ tuple ๋“ฑ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋ฅผ ์ œ์™ธํ•˜๋ฉด ์›ฌ๋งŒํ•˜๋ฉด `Interface`๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
- Type Alias์™€ Interface ๋‘˜๋‹ค ๊ธฐ๋Šฅ์€ ๋น„์Šท๋น„์Šทํ•˜์ง€๋งŒ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ๋ณด๋ฉด ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” interface๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  union, tuple ๋“ฑ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ type ๋ณ„์นญ์„ ์‚ฌ์šฉํ•˜๋ผ๋Š” TypeScript ๊ณต์‹ ๋ฌธ์„œ์˜ ๋‚ด์šฉ์ด ์กด์žฌํ•œ๋‹ค.


## โœจ 6. Redux-Saga

- Redux ๋ฏธ๋“ค์›จ์–ด๋กœ๋Š” ์ฃผ๋กœ thunk์™€ saga๊ฐ€ ์žˆ๋‹ค.
- saga๋Š” thunk๋กœ ๋ชปํ•˜๋Š” ๋‹ค์–‘ํ•œ ์ž‘์—…๋“ค์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
1. ๋น„๋™๊ธฐ ์ž‘์—…์„ ํ•  ๋•Œ ๊ธฐ์กด ์š”์ฒญ์„ ์ทจ์†Œ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
2. ํŠน์ • ์•ก์…˜์ด ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์ด์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ์•ก์…˜์ด ๋””์ŠคํŒจ์น˜๋˜๊ฒŒ๋” ํ•˜๊ฑฐ๋‚˜, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
3. ์›น์†Œ์ผ“์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ Channel ์ด๋ผ๋Š” ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋”์šฑ ํšจ์œจ์ ์œผ๋กœ ์ฝ”๋“œ๋ฅผ ๊ด€๋ฆฌ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค
4. API ์š”์ฒญ์ด ์‹คํŒจํ–ˆ์„ ๋•Œ ์žฌ์š”์ฒญํ•˜๋Š” ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- ์ด์™ธ์—๋„ ๋‹ค์–‘ํ•œ ๊นŒ๋‹ค๋กœ์šด ๋น„๋™๊ธฐ ์ž‘์—…๋“ค์„ saga๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.


### Redux-saga Effects

- [Redux-saga Effects ์ฐธ๊ณ  ์‚ฌ์ดํŠธ](https://blog.naver.com/ssi02014/222586185773)
- Redux-saga Effects ์ข…๋ฅ˜๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.
1. `all`: ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜๋ฅผ ๋ฐฐ์—ด์˜ ํ˜•ํƒœ๋กœ ์ธ์ž๋กœ ๋„ฃ์–ด์ฃผ๋ฉด ๋™์‹œ ์‹คํ–‰ํ•œ๋‹ค. (์‰ฝ๊ฒŒ ์ƒ๊ฐํ•˜๋ฉด ์—ฌ๋Ÿฌ ์‚ฌ๊ฐ€๋ฅผ ํ•ฉ์ณ์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.)
2. `fork`: ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค. ์ด๋•Œ ๋น„๋™๊ธฐ์ ์ธ ํ˜ธ์ถœ์„ ํ•œ๋‹ค.
3. `call`: fork์™€ ๊ฐ™์ด ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•œ๋‹ค. ๋‹จ, ๋™๊ธฐ์ ์ธ ํ˜ธ์ถœ์„ ํ•œ๋‹ค.
4. `put`: ํŠน์ • ์•ก์…˜์˜ ๋””์ŠคํŒจ์น˜ํ•˜๋„๋ก ํ•œ๋‹ค. ๊ฒฐ๊ณผ๋ฅผ ์Šคํ† ์–ด์— ๋””์ŠคํŒจ์น˜ํ•œ๋‹ค.
5. `take`: 1ํšŒ์šฉ ์•ก์…˜ ํ˜ธ์ถœ์šฉ ์ด๋‹ค.
6. `takeEvery`: ์•ก์…˜์ด ๋ฐœ์ƒํ•˜๊ฒŒ๋˜๋ฉด task๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. task๊ฐ€ ์ข…๋ฃŒ๋˜๊ธฐ ์ „์— ๋˜ ๋‹ค๋ฅธ ์•ก์…˜์ด ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ, ๋˜ ํ•˜๋‚˜์˜ ์ƒˆ๋กœ์šด task๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. ์ฆ‰, ๋น„๋™๊ธฐ๋กœ ์‹คํ–‰๋˜๋Š”๋ฐ ๋งŒ์•ฝ ์‹ค์ˆ˜๋กœ ๋ฒ„ํŠผ์„ 2๋ฒˆ ๋ˆŒ๋ €์„ ๋•Œ 2๋ฒˆ ๋‹ค ์‹คํ–‰๋œ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.
7. `takeLatest`: ์•ก์…˜์ด ๋ฐœ์ƒํ•˜๊ฒŒ๋˜๋ฉด task๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. ๋งŒ์•ฝ ์‹คํ–‰์ค‘์ธ task๊ฐ€ ์žˆ๋‹ค๋ฉด ๊ธฐ์กด task๋ฅผ ์ข…๋ฃŒํ•˜๊ณ  ์ƒˆ๋กœ์šด task๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. ์ฆ‰, ํ•ญ์ƒ ์ตœ์‹ ์˜ ์•ก์…˜์ด ์ฒ˜๋ฆฌ๋˜๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•œ๋‹ค. `(๋Œ€๋ถ€๋ถ„ takeLatest๋ฅผ ์‚ฌ์šฉ)`
8. `takeLeading`: ์•ก์…˜์ด ๋ฐœ์ƒํ•˜๊ฒŒ ๋˜๋ฉด task๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. ํ•ด๋‹น task์˜ ์‹คํ–‰์ด ์™„๋ฃŒ๋˜๊ธฐ ์ „๊นŒ์ง€ ๋’ค์— ์˜ค๋Š” ์ด๋ฒคํŠธ๋“ค์€ ๋ชจ๋‘ ๋ธ”๋Ÿญํ•œ๋‹ค. ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด ๊ธฐ์กด task๊ฐ€ ๋๋‚ ๋•Œ๊นŒ์ง€ ๋™์ผํ•œ ์•ก์…˜์—๋Œ€ํ•ด ๊ฐ์ง€๋ฅผ ํ•˜์ง€ ์•Š๊ณ  ๋จผ์ € ํ˜ธ์ถœ๋œ ์•ก์…˜์„ ์ฒ˜๋ฆฌ๋˜๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•œ๋‹ค.
9. `throttle`: ํŠน์ • ์‹œ๊ฐ„ ์ด๋‚ด์— ์š”์ฒญ์„ ํ•œ ๋ฒˆ๋งŒ ๋ณด๋‚ธ๋‹ค. ๋งˆ์ง€๋ง‰ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋œ ํ›„ ์ผ์ • ์‹œ๊ฐ„์ด ์ง€๋‚˜๊ธฐ ์ „์— ๋‹ค์‹œ ํ˜ธ์ถœ์„ ํ•˜์ง€ ์•Š๋Š”๋‹ค.
10. `delay`: ์„ค์ •๋œ ์‹œ๊ฐ„ ์ดํ›„์— resolve๋ฅผ ํ•˜๋Š” Promise ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค. ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋ฅผ ์ •์ง€ํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.


## โœจ 7. immer(๋„์ž… ๊ณ ๋ฏผ์ค‘)

- immer๋ž€? react์—์„œ `๋ถˆ๋ณ€์„ฑ์„ ์œ ์ง€`ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์‰ฝ๊ฒŒ ํ•ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ


### ๋ถˆ๋ณ€์„ฑ

- ์‚ฌ์ „์ ์œผ๋กœ ๋ถˆ๋ณ€์„ฑ์ด๋ž€ ๊ฐ’์ด๋‚˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.


### react์˜ ๊ธฐ๋ณธ ์†์„ฑ

- react๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง์„ ํ•˜๋ฉด ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋„ ๋ฆฌ๋ Œ๋”๋ง๋œ๋‹ค. ์ฆ‰ `์–•์€ ๋น„๊ต`๋ฅผ ํ†ตํ•ด ์ƒˆ๋กœ์šด ๊ฐ’์ธ์ง€ ์•„๋‹Œ์ง€ ํŒ๋‹จ ํ›„์— ์ƒˆ๋กœ์šด ๊ฐ’์ธ ๊ฒฝ์šฐ ๋ฆฌ๋ Œ๋”๋ง์„ ํ•œ๋‹ค.
- ์—ฌ๊ธฐ์„œ ์–•์€ ๋น„๊ต๋ž€ ๊ฐ„๋‹จํžˆ ๋งํ•˜๋ฉด ๊ฐ์ฒด, ๋ฐฐ์—ด, ํ•จ์ˆ˜์™€ ๊ฐ™์€ ์ฐธ์กฐ ํƒ€์ž…๋“ค์„ ์‹ค์ œ ๋‚ด๋ถ€ ๊ฐ’๊นŒ์ง€ ๋น„๊ตํ•˜์ง€ ์•Š๊ณ  ๋™์ผํ•œ ์ฐธ์กฐ์ธ์ง€(๋™์ผํ•œ ๋ฉ”๋ชจ๋ฆฌ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋Š”์ง€)๋ฅผ ๋น„๊ตํ•˜๋Š” ๊ฒƒ์„ ๋œปํ•œ๋‹ค.


### ์–•์€ ๋น„๊ต State

- state๊ฐ€ ์–•์€ ๋น„๊ต๋ฅผ ํ†ตํ•ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋œ๋‹ค๋Š” ๋ง์€ ๊ต‰์žฅํžˆ ์˜๋ฏธ๊ฐ€ ์žˆ๋‹ค. ์•„๋ž˜์˜ ๊ณผ์ •์„ ๋ณด๋ฉด ์™œ react์—์„œ ์š”์†Œ๋ฅผ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜๋ฉด ์•ˆ๋˜๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

```
1. ์šฐ๋ฆฌ๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฆฌ๋ Œ๋”๋ง ํ•ด์•ผํ•˜๋Š” ์ƒํ™ฉ์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ , ํƒ€์ž…์ด ๋ฐฐ์—ด์ธ state๋ฅผ ๋ฐ”๊พผ๋‹ค.
2. ์ด๋•Œ, state.push(1)์„ ํ†ตํ•ด state ๋ฐฐ์—ด์— ์ง์ ‘ ์ ‘๊ทผํ•˜์—ฌ ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
3. ์šฐ๋ฆฌ๋Š” push ์ „๊ณผ ๋‹ค๋ฅธ ๊ฐ’์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ, react๋Š” state๋ผ๋Š” ๊ฐ’์€ ์ƒˆ๋กœ์šด ์ฐธ์กฐ๊ฐ’์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด์ „๊ณผ ๊ฐ™์€ ๊ฐ’์ด๋ผ๊ณ  ์ธ์‹ํ•˜๊ณ  ๋ฆฌ๋ Œ๋”๋งํ•˜์ง€ ์•Š๋Š”๋‹ค.
```

- ์ฆ‰ ์œ„์™€ ๊ฐ™์€ ์ด์œ ๋กœ ์šฐ๋ฆฌ๊ฐ€ state๋ฅผ ๋ฐ”๊พธ๊ณ  DOM์„ ๋‹ค์‹œ ๋งŒ๋“ค๋ ค๋ฉด, ์ƒˆ๋กœ์šด ๊ฐ์ฒด or ๋ฐฐ์—ด์„ ๋งŒ๋“ค์–ด ์ƒˆ๋กœ์šด ์ฐธ์กฐ๊ฐ’์„ ๋งŒ๋“ค๊ณ , react์—๊ฒŒ ์ด ๊ฐ’์€ ์ด์ „๊ณผ ๋‹ค๋ฅธ ์ฐธ์กฐ๊ฐ’์ž„์„ ์•Œ๋ ค์ค˜์•ผ ํ•œ๋‹ค.

### immer ์˜ˆ์ œ

```js
const initialState = [
{ name: "minjae", address: { city: "seoul" }}
];

export default function auth(state = initialState, action) {
switch (action.type) {
case SET_INFO:
return {
...state,
name: "manjae",
address : {
...state.address,
city: "busan"
},
};
case ADD_INFO:
return {
...state,
{ name: "yenojae", address: { city: "seoul" }},
};
default:
return state;
}
}
```

- ์œ„ ์˜ˆ์ œ๋Š” immer.js๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „ redux reducer ์ฝ”๋“œ์ด๋‹ค.
- `...(spread ์—ฐ์‚ฐ์ž)`๋กœ ๊ฐ์ฒด๋ฅผ depth 1๋งŒํผ ๊นŠ์€ ๋ณต์‚ฌ๋ฅผ ํ•ด์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š”๋ฐ, ์ฝ”๋“œ๊ฐ€ ๋‚œ์žกํ•˜๋‹ค.


```js
const initialState = [{ name: "minjae", address: { city: "seoul" } }];

export default function auth(state = initialState, action) {
produce(state, (draft) => {
switch (action.type) {
case SET_INFO:
draft[0].name = action.data.name;
draft[0].address.city = action.data.city;
break;
case ADD_INFO:
draft.push({ name: "yenojae", address: { city: "seoul" } });
default:
return state;
}
});
}
```

- ์œ„ ์ฝ”๋“œ๋Š” immer๋ฅผ ์‚ฌ์šฉํ•œ reduce ์ฝ”๋“œ์ด๋‹ค.
- immer ์—์„œ๋Š” `produce` ํ•จ์ˆ˜๋งŒ ์•Œ๋ฉด ๋œ๋‹ค. 2๊ฐœ์˜ ์ธ์ž๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ์ฒซ ๋ฒˆ์งธ๋Š” ์ˆ˜์ •ํ•˜๊ณ  ์‹ถ์€ ๊ฐ์ฒด/๋ฐฐ์—ด์ด๊ณ , ๋‘ ๋ฒˆ์งธ๋Š” ์ฒซ ๋ฒˆ์งธ ์ธ์ž์— ํ• ๋‹น๋œ ๊ฐ์ฒด/๋ฐฐ์—ด์„ ๋ฐ”๊พธ๋Š” ํ•จ์ˆ˜์ด๋‹ค.
- ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด draft๊ฐ€ state๋ผ ์ƒ๊ฐํ•˜๊ณ  push๋‚˜ unshift๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ์ฒด/๋ฐฐ์—ด์„ ์ˆ˜์ •ํ•œ๋‹ค.