React ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ท๋ชจ๊ฐ ์ปค์ง๋ฉด์ ์ํ ๊ด๋ฆฌ๋ ๊ฐ๋ฐ์ ํต์ฌ์ ์ธ ๊ณผ์ ๊ฐ ๋์์ต๋๋ค. ๊ธฐ์กด์ Redux๋ MobX์ ๊ฐ์ ํ๋ฅญํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด ์์ง๋ง, ๋๋ก๋ ์ค์ ์ ๋ณต์ก์ฑ์ด๋ ๋ฌ๋ ์ปค๋ธ ๋๋ฌธ์ ์์ ํ๋ก์ ํธ์ ๋์ ํ๊ธฐ ๋ถ๋ด์ค๋ฌ์ธ ๋๊ฐ ์์ต๋๋ค. ๋ฐ๋ก ์ด๋ฌํ ๊ณ ๋ฏผ์ ํด๊ฒฐํ๊ธฐ ์ํด Facebook์์ ์ง์ ๊ฐ๋ฐํ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ Recoil์ ๋๋ค.
์ด ๊ธ์์๋ Recoil์ด ๋ฌด์์ธ์ง, ์ ๋ฑ์ฅํ๋์ง๋ถํฐ ์์ํ์ฌ ๊ธฐ์ด ๊ฐ๋ ์ธ Atom๊ณผ Selector์ ์ฌ์ฉ๋ฒ์ ์ตํ๊ณ , ๋์๊ฐ ๋น๋๊ธฐ ์ฒ๋ฆฌ, ์ํ ๋๊ธฐํ์ ๊ฐ์ ์ฌํ ์ฃผ์ ๊น์ง ๊น์ด ์๊ฒ ํ๊ตฌํด ๋ณด๊ฒ ์ต๋๋ค. ์ด ๊ธ์ ๋๊น์ง ์ฝ์ผ์ ๋ค๋ฉด Recoil์ ํ์ฉํ์ฌ ๋ณต์กํ React ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ๋ฅผ ์ผ๋ง๋ ๊ฐ๊ฒฐํ๊ณ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์๋์ง ์๋ฒฝํ๊ฒ ์ดํดํ๊ฒ ๋ ๊ฒ์ ๋๋ค.
1. Recoil์ ๋ฑ์ฅ ๋ฐฐ๊ฒฝ: ์ ์๋ก์ด ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํ์ํ์๊น?
Recoil์ ์ดํดํ๊ธฐ ์ ์ ๋จผ์ ๊ธฐ์กด ์ํ ๊ด๋ฆฌ ๋ฐฉ์์ ํ๊ณ๋ฅผ ์ง์ด๋ณผ ํ์๊ฐ ์์ต๋๋ค.
- ์ปดํฌ๋ํธ ํธ๋ฆฌ๋ฅผ ํตํ props ์ ๋ฌ (Prop Drilling): ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ React์ ์ํ ์ ๋ฌ ๋ฐฉ์์ ๋๋ค. ํ์ง๋ง ์ํ๊ฐ ํ์ํ ์ปดํฌ๋ํธ๊ฐ ์ต์์ ์ปดํฌ๋ํธ์ ๋ฉ๋ฆฌ ๋จ์ด์ ธ ์์ ๊ฒฝ์ฐ, ์ค๊ฐ์ ์๋ ์๋ง์ ์ปดํฌ๋ํธ๋ค์ด ์ค์ง ์ํ๋ฅผ ์ ๋ฌํ๊ธฐ ์ํ ๋ชฉ์ ์ผ๋ก props๋ฅผ ๋ฐ์์ผ ํ๋ 'Prop Drilling' ํ์์ด ๋ฐ์ํฉ๋๋ค. ์ด๋ ์ฝ๋์ ๊ฐ๋ ์ฑ์ ํด์น๊ณ ์ ์ง๋ณด์๋ฅผ ์ด๋ ต๊ฒ ๋ง๋ญ๋๋ค.
- Context API: React์ ๋ด์ฅ๋ Context API๋ Prop Drilling ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ฑ์ฅํ์ต๋๋ค. ์ ์ญ์ ์ธ ์ํ๋ฅผ ๋ง๋ค์ด ํ์ํ ์ปดํฌe๋ํธ์์ ์ง์ ์ ๊ทผํ ์ ์๊ฒ ํด ์ฃผ์ฃ . ํ์ง๋ง Context๋ ์ํ๊ฐ ๋ณ๊ฒฝ๋ ๋ ํด๋น Context๋ฅผ ๊ตฌ๋ ํ๋ ๋ชจ๋ ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง ๋๋ ๋จ์ ์ด ์์ต๋๋ค. ์ํ์ ์ผ๋ถ๋ง ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ๊น์ง ๋ถํ์ํ๊ฒ ๋ฆฌ๋ ๋๋ง ๋์ด ์ฑ๋ฅ ์ ํ์ ์์ธ์ด ๋ ์ ์์ต๋๋ค.
- Redux: Redux๋ ์ค๋ซ๋์ React ์ํ๊ณ์ ํ์ค์ฒ๋ผ ์ฌ๊ฒจ์ ธ ์จ ๊ฐ๋ ฅํ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. ํ์ง๋ง Action, Reducer, Store, Middleware ๋ฑ ๋ฐฐ์์ผ ํ ๊ฐ๋ ์ด ๋ง๊ณ , ๊ฐ๋จํ ์ํ ํ๋๋ฅผ ์ถ๊ฐํ๋๋ผ๋ ์์ฑํด์ผ ํ๋ ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋๊ฐ ์๋นํฉ๋๋ค. ์ด๋ก ์ธํด ๊ฐ๋ฐ ์๋๊ฐ ์ ํ๋๊ณ ์ ๋ฌธ์์๊ฒ ๋์ ์ฅ๋ฒฝ์ผ๋ก ๋๊ปด์ง๊ธฐ๋ ํฉ๋๋ค.
Recoil์ ๋ฐ๋ก ์ด๋ฌํ ๋ฌธ์ ๋ค์ ํด๊ฒฐํ๊ณ , ๋ 'React'์ค๋ฌ์ด ๋ฐฉ์์ผ๋ก ์ํ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํด ํ์ํ์ต๋๋ค. React์ useState ํ ์ฒ๋ผ ๊ฐ๋จํ๊ฒ ์์ํ ์ ์์ผ๋ฉด์๋, ๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์ ์์๋ ์ ์ฐํ๊ณ ๊ฐ๋ ฅํ๊ฒ ์ํ๋ฅผ ๊ด๋ฆฌํ ์ ์๋ ๋๊ตฌ๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ด Recoil์ ํต์ฌ ์ฒ ํ์ ๋๋ค.
2. Recoil์ ํต์ฌ ๊ฐ๋ : Atom๊ณผ Selector
Recoil์ API๋ ๋งค์ฐ ์ง๊ด์ ์ด๊ณ ๊ฐ๋จํฉ๋๋ค. ๊ทธ ์ค์ฌ์๋ Atom๊ณผ Selector๋ผ๋ ๋ ๊ฐ์ง ํต์ฌ ๊ฐ๋ ์ด ์์ต๋๋ค.
Atom: ์ํ์ ์ต์ ๋จ์
Atom์ Recoil์์ ์ํ์ ๊ฐ์ฅ ์์ ๋จ์์ ๋๋ค. ๋ง์น React์ useState์ฒ๋ผ ํ๋์ ์ํ ๊ฐ์ ๊ฐ์ง๋ฉฐ, ์ด๋ค ์ปดํฌ๋ํธ๋ ์ด Atom์ ๊ตฌ๋ ํ์ฌ ๊ฐ์ ์ฝ๊ณ ์ ๋ฐ์ดํธํ ์ ์์ต๋๋ค. Atom์ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด, ํด๋น Atom์ ๊ตฌ๋ ํ๊ณ ์๋ ๋ชจ๋ ์ปดํฌ๋ํธ๋ค์ด ์๋์ผ๋ก ๋ฆฌ๋ ๋๋ง๋ฉ๋๋ค.
Atom์ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค.
// store/atoms.ts
import { atom } from 'recoil';
export const todoListState = atom<string[]>({
key: 'todoListState', // ์ ํ๋ฆฌ์ผ์ด์
์ ์ฒด์์ ๊ณ ์ ํ ํค
default: [], // ๊ธฐ๋ณธ๊ฐ
});
- key: ์์ฑ๋ Atom์ ์๋ณํ๊ธฐ ์ํ ๊ณ ์ ํ ๋ฌธ์์ด์ ๋๋ค. ์ด ํค๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฒด์์ ์ ์ผํด์ผ ํฉ๋๋ค.
- default: ํด๋น Atom์ ์ด๊ธฐ๊ฐ์ ์๋ฏธํฉ๋๋ค.
์ด์ ์ปดํฌ๋ํธ์์ ์ด Atom์ ์ฌ์ฉํด ๋ณด๊ฒ ์ต๋๋ค. Recoil์ React ํ ๊ณผ ์ ์ฌํ API๋ฅผ ์ ๊ณตํ์ฌ ์ฝ๊ฒ ์ํ๋ฅผ ์ฌ์ฉํ๊ณ ์กฐ์ํ ์ ์์ต๋๋ค.
// components/TodoList.jsx
import { useRecoilState } from 'recoil';
import { todoListState } from '../store/atoms';
function TodoList() {
// useState์ ๋งค์ฐ ์ ์ฌํ ๋ฐฉ์
const [todos, setTodos] = useRecoilState(todoListState);
// ... (์์ดํ
์ถ๊ฐ, ์ญ์ ๋ก์ง)
}
useRecoilState ํ ์ useState์ ๋๊ฐ์ด [๊ฐ, ์ ๋ฐ์ดํธ ํจ์] ํํ์ ๋ฐฐ์ด์ ๋ฐํํฉ๋๋ค. ์ด ์ธ์๋ ๊ฐ๋ง ํ์ํ ๋๋ useRecoilValue, ์ ๋ฐ์ดํธ ํจ์๋ง ํ์ํ ๋๋ useSetRecoilState๋ฅผ ์ฌ์ฉํ์ฌ ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
Selector: ํ์๋ ์ํ (Derived State)
Selector๋ Recoil์ ์ง์ ํ ๊ฐ๋ ฅํจ์ด ๋๋ฌ๋๋ ๋ถ๋ถ์ ๋๋ค. Selector๋ ๊ธฐ์กด Atom์ด๋ ๋ค๋ฅธ Selector์ ์ํ๋ฅผ ์ ๋ ฅ๋ฐ์ **์๋ก์ด ํ์๋ ๋ฐ์ดํฐ(Derived State)**๋ฅผ ๋ง๋ค์ด๋ด๋ ์์ ํจ์์ ๋๋ค.
์๋ฅผ ๋ค์ด, ์ ์ฒดํ ์ผ ๋ชฉ๋ก(todoListState)์์ ์๋ฃ๋์ง ์์ ํ ์ผ์ ๊ฐ์๋ง ๋ฐ๋ก ๊ณ์ฐํ๊ณ ์ถ๋ค๊ณ ๊ฐ์ ํด ๋ด ์๋ค. ์ด๋ด ๋ Selector๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
// store/selectors.ts
import { selector } from 'recoil';
import { todoListState } from './atoms';
export const uncompletedTodoCountState = selector<number>({
key: 'uncompletedTodoCountState',
get: ({ get }) => {
// get ํจ์๋ฅผ ํตํด ๋ค๋ฅธ atom์ด๋ selector์ ๊ฐ์ ๊ฐ์ ธ์ฌ ์ ์๋ค.
const todoList = get(todoListState);
return todoList.filter(item => !item.isCompleted).length;
},
});
- key: Selector๋ฅผ ์๋ณํ๊ธฐ ์ํ ๊ณ ์ ํ ํค์ ๋๋ค.
- get: ํ์๋ ๋ฐ์ดํฐ๋ฅผ ๊ณ์ฐํ๋ ์์ ํจ์์ ๋๋ค. get ํ๋กํผํฐ์ ์ฝ๋ฐฑ ํจ์๋ get์ด๋ผ๋ ์ธ์๋ฅผ ๋ฐ๋๋ฐ, ์ด๋ฅผ ํตํด ๋ค๋ฅธ Atom์ด๋ Selector์ ์ต์ ๊ฐ์ ์ ๊ทผํ ์ ์์ต๋๋ค.
Recoil์ ์์กด์ฑ ๊ทธ๋ํ๋ฅผ ์๋์ผ๋ก ์ถ์ ํฉ๋๋ค. ์ฆ, uncompletedTodoCountState๋ todoListState์ ์์กดํ๊ณ ์์ผ๋ฏ๋ก, todoListState๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง get ํจ์๊ฐ ์ฌ์คํ๋์ด ๊ฐ์ ๋ค์ ๊ณ์ฐํฉ๋๋ค. ๋ง์ฝ ๊ด๋ จ ์๋ ๋ค๋ฅธ Atom์ด ๋ณ๊ฒฝ๋๋๋ผ๋ ์ด Selector๋ ์ฌ๊ณ์ฐ๋์ง ์์ ๋ฐ์ด๋ ์ฑ๋ฅ์ ๋ณด์ฅํฉ๋๋ค.
์ปดํฌ๋ํธ์์๋ Selector๋ฅผ ์ฝ๊ธฐ ์ ์ฉ ๊ฐ์ฒ๋ผ useRecoilValue๋ก ๊ตฌ๋ ํ์ฌ ์ฌ์ฉํ ์ ์์ต๋๋ค.
// components/TodoStats.jsx
import { useRecoilValue } from 'recoil';
import { uncompletedTodoCountState } from '../store/selectors';
function TodoStats() {
const count = useRecoilValue(uncompletedTodoCountState);
return <div>๋จ์ ํ ์ผ: {count}๊ฐ</div>;
}
์ด์ฒ๋ผ Selector๋ฅผ ์ฌ์ฉํ๋ฉด ์ํ ๋ก์ง์ ์ปดํฌ๋ํธ๋ก๋ถํฐ ๋ถ๋ฆฌํ์ฌ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ๊ณ ๊ด๋ฆฌํ๊ธฐ ์ฌ์ด ํํ๋ก ๋ง๋ค ์ ์์ต๋๋ค.
3.Recoil ์ ๋๋ก ํ์ฉํ๊ธฐ
Atom๊ณผ Selector์ ๊ธฐ๋ณธ ๊ฐ๋ ์ ์ดํดํ๋ค๋ฉด, ์ด์ Recoil์ ๋์ฑ ๊ฐ๋ ฅํ๊ฒ ๋ง๋ค์ด์ฃผ๋ ์ฌํ ๊ธฐ๋ฅ๋ค์ ์์๋ณผ ์ฐจ๋ก์ ๋๋ค.
๋น๋๊ธฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ (Asynchronous Selectors)
ํ๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋น๋๊ธฐ ๋ฐ์ดํฐ ์์ฒญ์ ํ์์ ์ ๋๋ค. Recoil์ Selector๋ async/await๋ฅผ ์ง์ํ์ฌ ๋น๋๊ธฐ ๋ก์ง์ ๋งค์ฐ ์ฐ์ํ๊ฒ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
get ํจ์๋ฅผ async๋ก ๋ง๋ค๋ฉด, Promise๋ฅผ ๋ฐํํ๋ ๋น๋๊ธฐ ์์ ์ ์ํํ ์ ์์ต๋๋ค. Recoil์ ๋ด๋ถ์ ์ผ๋ก React Suspense์ ์ฐ๋ํ์ฌ ๋ฐ์ดํฐ๊ฐ ๋ก๋ฉ ์ค์ผ ๋ fallback UI๋ฅผ ๋ณด์ฌ์ฃผ๊ณ , ๋ก๋ฉ์ด ์๋ฃ๋๋ฉด ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋ง ํฉ๋๋ค.
// store/selectors.ts
import { selector } from 'recoil';
import axios from 'axios';
export const userState = selector({
key: 'userState',
get: async ({ get }) => {
// ๋ค๋ฅธ atom์ ๊ฐ์ ๋ฐ๋ผ API ์์ฒญ์ ๋์ ์ผ๋ก ๋ณ๊ฒฝํ ์๋ ์๋ค.
// const userId = get(currentUserIDState);
try {
const response = await axios.get(`https://api.example.com/user/1`);
return response.data;
} catch (error) {
throw error; // ์๋ฌ ๋ฐ์ ์ Error Boundary๋ก ์ ํ
}
},
});
์ปดํฌ๋ํธ์์๋ ์ด ๋น๋๊ธฐ Selector๋ฅผ ์ผ๋ฐ Selector์ ๋๊ฐ์ด ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค. ๋ฐ์ดํฐ ๋ก๋ฉ ์ํ ๊ด๋ฆฌ๋ฅผ ์ํด ๋ณ๋์ isLoading, error ์ํ๋ฅผ ๋ง๋ค ํ์ ์์ด, React Suspense์ Error Boundary๋ฅผ ์กฐํฉํ์ฌ ์ ์ธ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
// components/UserInfo.jsx
import { Suspense } from 'react';
import { useRecoilValue } from 'recoil';
import { userState } from '../store/selectors';
function UserInfoComponent() {
const user = useRecoilValue(userState);
return <div>์ฌ์ฉ์ ์ด๋ฆ: {user.name}</div>;
}
function UserInfo() {
return (
<Suspense fallback={<div>๋ก๋ฉ ์ค...</div>}>
<UserInfoComponent />
</Suspense>
);
}
์ํ์ ์ก์ ์ ๋ชจ๋ ํ์๋ก ํ ๋: useRecoilCallback
๋๋ก๋ ํน์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ Recoil ์ํ๋ฅผ ์ฝ๊ฑฐ๋ ์ ๋ฐ์ดํธํด์ผ ํ์ง๋ง, ํด๋น ์ปดํฌ๋ํธ๋ฅผ ๋ฆฌ๋ ๋๋ง ์ํค๊ณ ์ถ์ง๋ ์์ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ฒํผ ํด๋ฆญ ์ ํ์ฌ ์ํ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก API ์์ฒญ์ ๋ณด๋ด๋ ๊ฒฝ์ฐ๊ฐ ๊ทธ๋ ์ต๋๋ค.
์ด๋ useRecoilCallback ํ ์ ์ฌ์ฉํ๋ฉด, ์ปดํฌ๋ํธ๊ฐ ํน์ Recoil ์ํ๋ฅผ ๊ตฌ๋ (๋ฆฌ๋ ๋๋ง) ํ์ง ์์ผ๋ฉด์๋ ํ์ํ ๋ ์ํ์ ์ค๋ ์์ ์ฝ๊ฑฐ๋ ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ ํจ์๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
import { useRecoilCallback } from 'recoil';
import { todoListState } from '../store/atoms';
function TodoListLogger() {
const logTodos = useRecoilCallback(({ snapshot }) => async () => {
// loadable์ ํตํด ๋น๋๊ธฐ selector์ ์ํ(loading, hasValue, hasError)๋ ์ ์ ์๋ค.
const todoList = await snapshot.getPromise(todoListState);
console.log('ํ์ฌ ํ ์ผ ๋ชฉ๋ก:', todoList);
});
return <button onClick={logTodos}>ํ์ฌ ๋ชฉ๋ก ์ฝ์์ ๊ธฐ๋ก</button>;
}
snapshot ๊ฐ์ฒด๋ ์ฝ๋ฐฑ์ด ์คํ๋๋ ์์ ์ Recoil ์ํ๋ฅผ ๋ด๊ณ ์์ด, ์์ ํ๊ฒ ์ํ๋ฅผ ์ฝ์ด์ฌ ์ ์์ต๋๋ค.
์ํ ์ง์์ฑ ๋ฐ ๋๊ธฐํ: Atom Effects
์ฌ์ฉ์๊ฐ ์ค์ ํ ํ ๋ง๋ ๋ก๊ทธ์ธ ์ ๋ณด ๋ฑ์ ํ์ด์ง๋ฅผ ์ ๋ก๊ณ ์นจํด๋ ์ ์ง๋์ด์ผ ํฉ๋๋ค. Recoil์ Atom Effects๋ผ๋ ๊ฐ๋ ฅํ ๋ถ์ ํจ๊ณผ API๋ฅผ ์ ๊ณตํ์ฌ Atom์ ์ํ๋ฅผ ์ธ๋ถ ์คํ ๋ฆฌ์ง(localStorage, sessionStorage ๋ฑ)์ ๋๊ธฐํํ๊ฑฐ๋ ๋ค๋ฅธ ๋ถ์์ ์ธ ์์ ์ ์ฒ๋ฆฌํ ์ ์๊ฒ ํด ์ค๋๋ค.
atom์ ์ ์ํ ๋ effects ๋ฐฐ์ด์ ์ถ๊ฐํ์ฌ ์ด ๊ธฐ๋ฅ์ ํ์ฑํํ ์ ์์ต๋๋ค.
import { atom } from 'recoil';
// localStorage์ ๋๊ธฐํํ๋ ๊ฐ๋จํ effect
const localStorageEffect = key => ({ setSelf, onSet }) => {
const savedValue = localStorage.getItem(key);
if (savedValue != null) {
setSelf(JSON.parse(savedValue));
}
onSet((newValue, _, isReset) => {
isReset
? localStorage.removeItem(key)
: localStorage.setItem(key, JSON.stringify(newValue));
});
};
export const themeState = atom<'light' | 'dark'>({
key: 'themeState',
default: 'light',
effects: [
localStorageEffect('theme'),
],
});
- setSelf: Atom์ด ์ฒ์ ์ด๊ธฐํ๋ ๋ ํธ์ถ๋๋ฉฐ, ์คํ ๋ฆฌ์ง์ ๊ฐ์ผ๋ก Atom ์ํ๋ฅผ ์ค์ ํฉ๋๋ค.
- onSet: Atom์ ์ํ๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ํธ์ถ๋๋ฉฐ, ๋ณ๊ฒฝ๋ ๊ฐ์ ์คํ ๋ฆฌ์ง์ ์ ์ฅํฉ๋๋ค.
์ด์ฒ๋ผ Atom Effects๋ฅผ ํ์ฉํ๋ฉด ์ํ ๊ด๋ฆฌ ๋ก์ง๊ณผ ๋๊ธฐํ ๋ก์ง์ Atom ์ ์ ๋ด์ ์บก์ํํ์ฌ ์ฝ๋์ ์์ง๋๋ฅผ ๋์ผ ์ ์์ต๋๋ค. (์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ธ recoil-persist๋ recoil-sync๋ฅผ ์ฌ์ฉํ๋ฉด ๋ ๊ฐํธํ๊ฒ ๊ตฌํํ ์๋ ์์ต๋๋ค.)
4. ๊ฒฐ๋ก : Recoil, ๋น์ ์ ๋ค์ ํ๋ก์ ํธ๋ฅผ ์ํ ์ ํ
Recoil์ React์ ์ฒ ํ์ ๊ณ์นํ์ฌ ๋ฐฐ์ฐ๊ธฐ ์ฝ๊ณ ๊ฐ๊ฒฐํ๋ฉด์๋, ๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ณต์กํ ์ํ๊น์ง ํจ๊ณผ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์๋ ๊ฐ๋ ฅํ ๋๊ตฌ์ ๋๋ค.
- ๋ฎ์ ๋ฌ๋ ์ปค๋ธ: useState์ ์ ์ฌํ API๋ก React ๊ฐ๋ฐ์๋ผ๋ฉด ๋๊ตฌ๋ ์ฝ๊ฒ ์์ํ ์ ์์ต๋๋ค.
- ์ต์ํ์ ๋ณด์ผ๋ฌํ๋ ์ดํธ: Redux์ ๋น๊ตํ์ฌ ํจ์ฌ ์ ์ ์์ ์ฝ๋๋ก ์ํ๋ฅผ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
- ์ฑ๋ฅ ์ต์ ํ: ์ํ ๋ณ๊ฒฝ ์ ํด๋น ์ํ๋ฅผ ๊ตฌ๋ ํ๋ ์ปดํฌ๋ํธ๋ง ์ ํํ ๋ฆฌ๋ ๋๋ง ํ์ฌ ๋ถํ์ํ ๋ ๋๋ง์ ๋ฐฉ์งํฉ๋๋ค.
- ๊ฐ๋ ฅํ ๋น๋๊ธฐ ์ฒ๋ฆฌ: React Suspense์ ์์ฐ์ค๋ฝ๊ฒ ํตํฉ๋์ด ๋น๋๊ธฐ ๋ก์ง์ ์ ์ธ์ ์ด๊ณ ๊น๋ํ๊ฒ ์์ฑํ ์ ์์ต๋๋ค.
๋ฌผ๋ก Recoil์ด ๋ชจ๋ ํ๋ก์ ํธ์ ๋ง๋ณํต์น์ฝ์ ์๋ ์ ์์ต๋๋ค. ๋งค์ฐ ๋ณต์กํ ๋ฏธ๋ค์จ์ด๊ฐ ํ์ํ๊ฑฐ๋, ์ ํํ๋ ์ก์ -๋์คํจ์น ํจํด์ด ํ์ ๋ ์ ํฉํ ๊ฒฝ์ฐ Redux๊ฐ ์ฌ์ ํ ์ข์ ์ ํ์ผ ์ ์์ต๋๋ค.
ํ์ง๋ง ๋๋ถ๋ถ์ React ํ๋ก์ ํธ์์ Recoil์ ๊ฐ๋ฐ ์์ฐ์ฑ๊ณผ ์ ํ๋ฆฌ์ผ์ด์ ์ฑ๋ฅ์ด๋ผ๋ ๋ ๋ง๋ฆฌ ํ ๋ผ๋ฅผ ๋ชจ๋ ์ก์ ์ ์๋ ํ๋ฅญํ ๋์์ด ๋ ๊ฒ์ ๋๋ค. ๋น์ ์ ๋ค์ ํ๋ก์ ํธ์ Recoil์ ๋์ ํ์ฌ, ์ง๊ด์ ์ด๊ณ ์ฆ๊ฑฐ์ด ์ํ ๊ด๋ฆฌ์ ์ธ๊ณ๋ฅผ ๊ฒฝํํด ๋ณด์๊ธธ ๋ฐ๋๋๋ค.
'๐บ React & Next.js' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| FSD์ํคํ ์ฒ(Feature-Sliced Design) ๊ฐ์ด๋ (0) | 2025.10.15 |
|---|---|
| "๋ฐฐํฌ๋ ํ๋ฒ๋ง" Vercel CI/CD๋ก ์นผํด๋ฅผ ์๋น๊ธฐ๋ ๋ฒ (0) | 2025.09.23 |
| Recoil atom๋ง ์จ๋ดค๋ค๋ฉด ์ฃผ๋ชฉ! isLoading, isError์ ์๋ณํ๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ค์ ํจํด ๐ (0) | 2025.09.22 |
| Vercel๋ก Next.js ํ๋ก์ ํธ ์๋ ๋ฐฐํฌํ๊ธฐ (0) | 2025.08.31 |
| ๋ฆฌ์กํธ ์ํ ๊ด๋ฆฌ, Recoil ์ดํดํ๊ธฐ (4) | 2025.08.28 |