Recoil이란 React를 위해 Facebook에서 개발한 상태 관리 라이브러리이다.
React에선 보통 Redux를 이용해 상태 관리를 많이 하는데 Redux의 러닝커브 등과 같은 이유로 최근엔 Recoil의 이용자가 많아지고 있다.
// npm으로 설치
npm install recoil
// yarn으로 설치
yarn add recoil
Root Component에 RecoilRoot
로 컴포넌트를 감싸준다.
현재 프로젝트에선 React를 사용하고 있기때문에 App.js
파일에 적용을 해보겠다.
// App.js
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { RecoilRoot } from 'recoil';
import MainPage from './pages/MainPage';
import DetailPage from './pages/DetailPage';
function App() {
return (
<RecoilRoot>
<BrowserRouter>
<Routes>
<Route path="/" element={<MainPage />} />
<Route path="/detail/:id" element={<DetailPage />} />
</Routes>
</BrowserRouter>
</RecoilRoot>
);
}
export default App;
RecoilRoot
는 Redux에서 Provider를 이용하여 store를 설정했던 것과 비슷한 역할을 한다.
파일 상단에 RecoilRoot
를 recoil
로 부터 import 해 와야 한다.
atom은 상태(state)의 일부를 나타내는데, atom은 어느 컴포넌트에서나 읽고 쓸 수가 있다.
atom은 2개의 값을 요구하는데, key와 defaultValue이다.
// RecoilState.ts
import { atom } from 'recoil';
export type PostCardData = {
id: number;
org_name: string;
main_img: string;
strt_date: string;
end_date: string;
title: string;
major_code_name: string;
date: string;
};
export const searchResultsState = atom<PostCardData[]>({
key: 'searchResultsState',
default: [],
});
다른 컴포넌트에서 atom을 읽게 하기 위해서는 useRecoilValue()
를 사용해야 한다.
atom의 값을 읽는 컴포넌트는 암묵적으로 그 atom을 subscribe하고 있기 때문에 atom의 업데이트는 이 atom을 subscribe하고 있는 컴포넌트들을 리렌더해준다.
// useRecoillValue를 import 해온다.
// key 값으로 정해준 searchResultsState도 import 해준다.
import { useRecoilValue } from 'recoil';
import { searchResultsState } from '../RecoilState';
// useRecoilValue를 이용해 atom을 읽어와 searchResults에 저장했다.
const searchResults = useRecoilValue(searchResultsState);
컴포넌트에서 atom 값을 쓰게 하기 위해서는 useSetRecoilState()
를 이용해야 한다.
// useSetRecoilState를 import 해준다.
import { useSetRecoilState } from 'recoil';
// setSearchResults를 atom의 키 값인 searchResults를 set해주는 함수로 만들어준다.
const setSearchResults = useSetRecoilState(searchResultsState);
selector는 다른 상태(Atom 또는 다른 Selector)에 의존하는 상태를 생성하고 관리하는 방법이다.
우선 예시를 보자.
// atom 정의
const numberState = atom({
key: 'numberState',
default: 0,
});
// sqaureState를 atom의 파생 상태로 정의
const squareState = selector({
key: 'squareState',
get: ({ get }) => {
const num = get(numberState);
return num * num;
},
});
squareState
는 atom의 값에 의존하며, 그 값을 제곱해서 반환한다.
아직 우리나라 시장에서는 Redux를 선호하는 경향이 있지만 프로젝트의 규모와 팀의 방향성을 생각해서 Recoil을 사용해보는 것도 좋은 선택일 것 같다.