์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก Redux ๋ฅผ ๊ตฌํํ๋ค๊ฐ... ๋ฌธ์ ๊ฐ ๋ฐ๊ฒฌ๋๋ฉด์ ๋ญ๊ฐ ๋ด๊ฐ ์์ ํด์ ์ฐ๊ธฐ์๋ ๊ตฌ์กฐ๊ฐ ๋๊ฒ ๋ณต์กํ๋ค๋ ์๊ฐ์ด ๋ค์๋ค.
๊ฑฐ๊ธฐ์๋ถํฐ ๋ ์๋ฌธ์ ์ด ์ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก Redux๋ฅผ ๋ง์ด ์ฌ์ฉํ๋๊ฐ์๊ณ (๊ตฌํ ์ฉ์ด์ฑ์ ๋จ์ด์ง๋ ์ฑ๋ฅ์ด ๋ฐ์ด๋๊ฒ ์ข๋ค๋์ง ๊ทธ๋ฐ ์ฅ์ ์ด ์๋๊ฐ๋ฅผ ์์นญํ๊ธฐ ์์ํจ.. ), ๊ทธ ์ด์ ๋ ๋จ์ํ๊ฒ ๋๋ถ๋ถ์ ์ฌ์ฉ์๋ค์ด Redux๋ฅผ ์ฌ์ฉํ๋ ๋น์ฐํ ๊ธฐ์ ์ ์ต๋ํ๋ ์ ์ฅ์์๋ '์ฌ์ฉ์๋ค์ด ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ = ์ข์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํน์ ๋ฏฟ์๋งํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ'๋ผ๋ ์๊ฐ์ ํ๊ฒ ํ๊ธฐ ๋๋ฌธ์ธ ๋ฏํ๋ค.
Redux๋ ๋ณด์ผ๋ฌ ํ๋ ์ดํธ ์ฝ๋๋ฅผ ๋ง์ด ์์ฑํด์ผํ๋ ์์ฃผ ํฐ ๋จ์ ์ด ์๋๋ฐ ํ์์ ๋ฐ๋ผ Redux๋ฅผ ์ฌ์ฉํด์ผํ ์๋ ์๊ฒ ์ง๋ง, ์๋น์ค ์ฌ์ฉ๋์ด ๊ทธ๋ ๊ฒ ๊ฑฐ๋ํ์ง ์์ ํ๋ก๊ทธ๋จ์ด๋ ํน์ ํ๋ก๊ทธ๋จ์ ๊ฒฝ์ฐ์๋ '์ ์ญ ์ํ ๊ด๋ฆฌ' ๊ธฐ๋ฅ ํ๋๋ง์ ์ํด Redux ์ฒด์ ๋ฅผ ๊ตฌํํ๋ ๊ฒ์ด ๋๋ฌด ๊ณผํ์ง๋ ์์๊ฐ
์๋ฌดํผ ๊ทธ๋์ ๋ด๊ฐ ์ด๋ฒ์ ๊ฐ๋ฐํ ๊ฒ์ ์์ ๋๊ท๋ชจ ์๋น์ค ๋ ์๋๋ฐ๋ค๊ฐ, ์๋ฌด๋ฆฌ ๋์ฉ๋ ์๋น์ค์ ์ ์ฉํ๊ธฐ๋ ์์ง์ ๋ฌด๋ฆฌ๋ผ๋ ํ๋จ๋ค์ด ์๋ค๊ณ ํ๋๋ผ๋ facebook ์์๋ Recoil๋ก ์ํ๊ด๋ฆฌ๋ฅผ ๊ตฌํํด๋๋๋ฐ, ํ์ฐฝ ๋์ facebook๋ณด๋ค ํธ๋ํฝ์ ๋์ด๊ฐ๋ ํ๋ก๊ทธ๋จ์ ์งค ๊ฒฝ์ฐ๊ฐ ์ฝ๊ฒ ์์ผ๋ ค๋ ํ๋ ์๊ฐ๋ ๋ ๋ค.
๊ทธ๋์ ๊ณผ๊ฐํ๊ฒ ์ผ๋ ๋ฒ๋ ๊ตฌํํด๋์๋.. redux saga ์ slice๋ฅผ ์ญ์ ํ๊ณ ... Recoil๋ก ๋ณ๊ฒฝํ๋ ์์ ์ ํด๋ณด๋ ค๊ณ ํ๋ค.
About Redux.
1. React ์ ์ฉ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋๋ค. : React ๋ด๋ถ ๊ด์ ์์๋ ์ธ๋ถ์์ธ์ผ๋ก Store๊ฐ ์ทจ๊ธ๋๋ฉฐ, ๋์์ฑ ๋ชจ๋๋ฅผ ๊ตฌํํ๊ธฐ์ ํธํ์ฑ์ด ๋ถ์กฑํ๋ค๊ณ ์ฌ๊ฒจ์ง๋ค.
2. ๋ณต์กํ Boiler Plate ์ด๊ธฐ์ธํ ์ด ์๊ตฌ๋๋ค. : Store, Action, Reducer ๋ฑ ๋ค์ํ ๊ตฌ์ฑ ์์๊ฐ ํ์ํด ๋นํจ์จ์ ์ด๋ฉฐ ๋ฌ๋์ปค๋ธ๊ฐ ๋๋ค.
3. ๋น๋๊ธฐ ๋ฐ์ดํฐ์ ์ถ๊ฐ ๋ฆฌ์์ค๊ฐ ์๊ตฌ๋๋ค.: Redux-saga ๋ฑ ์ ์ญ ์ํ์ ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฅผ ํธ์ถํ๊ธฐ ์ํ 3rd Party ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํ์ํ๋ค.
์ด๋ฐ ๋จ์ ์ ๋ณด์ํ๊ธฐ ์ํด์ ๋์จ React์ ์ต์ ํ ๋ ์ ์ญ ์ํ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๋ฐ๋ก Recoil ์ด๋ผ๊ณ ํ๋ค.
ํ์ด์ค๋ถ์์ ๋ง๋ ์ํ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก, usestatue๋ฅผ ์ฌ์ฉํ๋ ๊ฒ ๋งํผ ์ฌ์ฉ์ด ๊ฐ๋จํ๋ฉด์๋ ์ํ๊ด๋ฆฌ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ํ ์ ์๊ฒ ํด์ค๋ค.
์ ์ญ์ํ์ ์ค์ /์ ์๊ฐ ๋งค์ฐ ์ฌ์ฐ๋ฉฐ, Recoil์ด ์ง์ํ๋ Hooks๋ก ์ด๋ฅผ get/setํ๊ธฐ ๋๋ฌธ์ React ๋ฌธ๋ฒ๊ณผ ๋งค์ฐ ์ ์ฌํ๋ค๊ณ ํ๋ค.
๊ณต์ Document
https://github.com/facebookexperimental/Recoil
1. ๊ณต์ ์ํ(Shared State)๋ React ๋ด๋ถ์ํ(Local State)์ฒ๋ผ ๊ฐ๋จํ get/set ์ธํฐํ์ด์ค๋ก ์ฌ์ฉํ ์ ์๋ Boilerplate-free API๋ฅผ ์ ๊ณต
2. ๋์์ฑ ๋ชจ๋(Concurrent Mode)๋ฅผ ๋น๋กํ ๋ค๋ฅธ ์๋ก์ด React์ ๊ธฐ๋ฅ๋ค๊ณผ์ ํธํ ๊ฐ๋ฅ์ฑ
3. ์ํ ์ ์๊ฐ ์ฆ๋ถ ๋ฐ ๋ถ์ฐ๋๋ฏ๋ก ์ฝ๋ ๋ถํ ์ด ๊ฐ๋ฅ
4. ์ํ๋ฅผ ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ์์ ์์ ํ ํ์ ์์ด, ์ํ์์ ํ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ์ ์์. ๋ํ, ํ์๋ ๋ฐ์ดํฐ๋ ๋๊ธฐ/๋น๋๊ธฐ๊ฐ ๋ชจ๋ ๊ฐ๋ฅ
5. ํ์์ 1๊ธ ๊ฐ๋ ์ผ๋ก ์ทจ๊ธํ ์ ์์ผ๋ฉฐ ์ฌ์ง์ด ๋งํฌ์์ ์ํ ์ ํ์ ์ธ์ฝ๋ฉํ ์ ์์.
6. ์ญํธํ์ฑ ๋ฐฉ์์ผ๋ก ์ ์ฒด ์ฑ ์ํ๋ฅผ ์ ์งํ๋ ๊ฒ์ ์ฌ์ฐ๋ฏ๋ก, ์ ์ง๋ ์ํ๋ ์ ํ๋ฆฌ์ผ์ด์ ๋ณ๊ฒฝ์๋ ์ด์๋จ์ ์ ์์. (์บ์ฑ)
Recoil์ ํน์ง
1. ์๊ณ React์ค๋ฌ์ด: "Recoil์ React์ฒ๋ผ ์๋ํ๊ณ ์๊ฐํ๋ค. ์ฑ์ ์ถ๊ฐํ์ฌ ๋น ๋ฅด๊ณ ์ ์ฐํ๊ฒ ๊ณต์ ๊ฐ ๋๋ ์ํ๋ฅผ ์ฌ์ฉํด๋ณด๋ผ"
2. ๋ฐ์ดํฐ ํ๋ฆ ๊ทธ๋ํ: "ํ์ ๋ฐ์ดํฐ์ ๋น๋๊ธฐ ์ฟผ๋ฆฌ๋ ์์ ํจ์์ ํจ์จ์ ์ธ ๊ตฌ๋ ์ผ๋ก ๊ด๋ฆฌ๊ฐ ๋๋ค."
3. ๊ต์ฐจํ๋ ์ฑ ๊ด์ฐฐ: "์ฝ๋ ๋ถํ ์ ์์์ํค์ง ์๊ณ ์ฑ ์ ์ฒด์ ๋ชจ๋ ์ํ ๋ณ๊ฒฝ์ ๊ด์ฐฐํ์ฌ ์ง์์ฑ, ๋ผ์ฐํ , ์๊ฐ ์ด๋ ๋๋ฒ๊น ๋๋ ์คํ ์ทจ์๋ฅผ ๊ตฌํํ๋ค."
๋๋ ์ด๋ฒ ์๋น์ค์์๋ ์ํ๊ด๋ฆฌ ํน์ ๋ผ์ฐํ ์ ๊ธฐ๋ฅ์ผ๋ก๋ง ์ด๊ฒ์ ์ฌ์ฉํด๋ณด๋๋ก ํ ๊ฒ์ธ๋ฐ.. ์๊ฐ ์ด๋ ๋๋ฒ๊น ์ด ๋ญ์ง ํ๋ฒ ์ฌ์ฉํด๋ณด๊ธฐ ์ํ ์์ ๋ฅผ ์กฐ๋ง๊ฐ ๋ง๋ค์ด๋ณด์์ผ๊ฒ ๋ค.
๐ผ Recoil ์์ํ๊ธฐ
1. Install ์ค์น
// npm(yarn)
npm install recoil
yarn add recoil
// CDN
<script src="https://cdn.jsdelivr.net/npm/recoil@0.0.11/umd/recoil.production.js"></script>
* Recoil์ Webpack๊ณผ ๊ฐ์ ๋ชจ๋ ๋ฒ๋ค๋ฌ์ ํธํ์ด ๋๋ฉฐ ES6 -> 5 ๋ก๋ ํธ๋์คํ์ผ๋ง ๋์ง ์๊ธฐ ๋๋ฌธ์ ํฌ๋ก์ค ๋ธ๋ผ์ฐ์ง์ ์ํด Babel์ ํตํ ์ฝ๋ ์ปดํ์ผ ๊ณผ์ ์ด ์๊ตฌ๋๋ค๊ณ ํ๋ค.
2. Apply ์ ์ฉ
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Router } from 'react-router-dom';
import reportWebVitals from './reportWebVitals';
import App from './App';
import { Provider } from "react-redux";
import store from "./utils/store";
import history from "./utils/history";
import {CookiesProvider} from 'react-cookie';
import './index.css';
import { RecoilRoot } from 'recoil';
// 1. recoil ์ฌ์ฉ ํฌ์ธํธ 1
ReactDOM.render(
<RecoilRoot> //2. recoil ์ฌ์ฉ ํฌ์ธํธ
<React.StrictMode>
<CookiesProvider>
<Provider store={store}>
<Router history={history}>
<App />
</Router>
</Provider>
</CookiesProvider>
</React.StrictMode>
</RecoilRoot>, //2. recoil ์ฌ์ฉ ํฌ์ธํธ
document.getElementById('root')
);
reportWebVitals();
์ฝ๋๊ฐ ๋งค์ฐ ๋์ง๋์ง์ด๋ค.
์๋ฌดํผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ recoil์ ๋ถ๋ฌ์์ index.js ํ์ผ์ <App/> ์ปดํฌ๋ํธ๋ฅผ <RecoilRoot> ๋ก ๊ฐ์ธ์ฃผ๋ฉด ๋๋ค.
3. Concept ํต์ฌ๊ฐ๋
๋ณธ๊ฒฉ์ ์ธ ๊ตฌํ์ ์ํ์ฌ ./src ๋ด์ recoil ํด๋๋ฅผ ๋ง๋ค์ด์ ์ ์ญ์ํ์ ๊ด๋ จ๋ Atoms, Selector ๋ค์ ์ค์ ํด์ฃผ์ด์ผ ํ๋ค.
Recoil ์ฌ์ฉ ์
Atom(๊ณต์ ์ํ)์์ Selector(์์ ํจ์)๋ฅผ ๊ฑฐ์ณ React Component๋ก ๋ด๋ ค๊ฐ๋ Data-flow Graph๋ฅผ ๋ง๋ค ์ ์๋ค.
- Atoms๋ ์ปดํฌ๋ํธ๊ฐ ๊ตฌ๋
ํ ์ ์๋ ์ํ์ ๋จ์
- Selectors๋ Atoms ์ํ ๊ฐ์ ๋๊ธฐ ํน์ ๋น๋๊ธฐ ๋ฐฉ์์ ํตํด ๋ณํ
- Recoil์์ ์ง์ํ๋ Hooks๋ค๋ก atom ํน์ selector์ get(์ ๊ทผ) ๋ฐ set(์์ ) ๋ฑ์ ๋ค์ํ ๋์์ด ๊ฐ๋ฅํด์ง๋ค.
(1) Atoms ์ค์
key์ default๋ฅผ ์ค์ ํด์ฃผ์ด์ผ ํ๋ค.
// /src/recoil/index.js
import { atom } from "recoil";
export const articleStates = atom({
key: 'articleState',
default: [],
})
export const commentStates = atom({
key: 'commentState',
default: [],
})
* default ๊ฐ์ Promise ๊ฐ์ฒด๋ ์ค์ ๊ฐ๋ฅํ๋, atom์์ ๋ฐ๋ก ๋น๋๊ธฐ ์์ฒญ์ ํ ์๋ ์๋ค.
(2) ์ ์ญ์ํ ๊ด๋ จ hooks
1. useRecoilState
- Atom์ ์ํ๋ฅผ ๊ตฌ๋ . useState Hook๊ณผ ๊ฐ์ด ๋ฐฐ์ด์ ์ฒซ๋ฒ์งธ ํ๋ผ๋ฏธํฐ๋ก ์ํ, ๋๋ฒ์งธ ํ๋ผ๋ฏธํฐ๋ก ์ํ์ ๋ํ setter ํจ์๋ฅผ ๋ฐํ.
2. useRecoilValue
- setter ํจ์ ์์ด Atom์ ์ํ๋ง ๋ฐํ
3. useSetRecoilState
- atom ์ํ ์์ด setter ํจ์๋ง ๋ฐํ
4. useResetRecoilState
- atom ์ํ๋ฅผ default ์ํ๋ก reset