Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
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
๐ฌ ๊ฐ์น๊ฐ์ ํํ๋ก์ ํธ ํ๋ก ํธ์๋ ํ ํ๋ฆฟ
- Host: GitHub
- URL: https://github.com/ssi02014/gachigayo_front_template
- Owner: ssi02014
- Created: 2021-12-15T13:57:20.000Z (about 3 years ago)
- Default Branch: master
- Last Pushed: 2021-12-23T12:29:43.000Z (about 3 years ago)
- Last Synced: 2024-11-08T01:52:43.270Z (2 months ago)
- Topics: react, redux, redux-saga, storybook, styled-components
- Language: TypeScript
- Homepage:
- Size: 353 KB
- Stars: 2
- Watchers: 2
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
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๊ฐ์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ ๊ฐ์ฒด/๋ฐฐ์ด์ ์์ ํ๋ค.