기존의 Redux와 같은 상태 관리 라이브러리들은 store 구성을 위해 많은 boilerplate 코드들을 필요로 하였고 이로 인하여 설정이 복잡해지게 되었다. Recoil은 이러한 문제의 해결과 전역 상태 관리의 최적화 및 성능과 효율성 향상을 위해 만들어졌다. 또한 React를 공식적으로 지원하는 상태 관리 라이브러리이기 때문에 React 내부에 접근이 가능하며 Concurrent 모드, Suspense 등을 손쉽게 사용할 수 있다. 이전에 React의 Hooks를 사용해봤다면 쉽게 적응하여 사용할 수 있다.
npm install recoil
Recoil에서 상태를 정의하는 개념. (Redux의 store와 유사한 개념)
컴포넌트가 구독할 수 있는 state이며 atom을 생성하기 위해 고유한 key와 default 값 설정이 필요.
atom의 값이 변경되면 해당 atom을 구독하고 있는 컴포넌트들이 모두 다시 re-render 됨.import { atom } from "recoil"; export default atom({ key: 'countState', default: 0, });
atom은 key와 default값을 설정해주어야합니다.
- key
atom을 식별하는데 필요한 고유한 문자열입니다.
프로젝트 전체에서 다른 atom, selector에 대해 고유해야합니다.- default
초기값을 설정해줍니다.import { atom } from "recoil"; export default atom({ key: 'countState', default: 0, });
파생된 상태(derived state)의 데이터를 의미.
read-only 객체이며 순수 함수.
Recoil에서 관리하는 상태의 일부만 선택하거나, 상태를 이용하여 연산한 값을 조회할 때 사용.
비동기 처리를 통해 atom에 의존적인 동적인 데이터 사용 가능.import { atom } from "recoil"; export default atom({ key: 'countState', default: 0, });
import { DefaultValue, selector } from "recoil"; import countState from "../atom/countState"; export default selector({ key: "countSelector", get: ({get}): number => { const count = get(countState); return count + 1; }, set: ({set, get}, newCount)=>{ return set(countState, newCount + 10) } })
selector는 총 세 가지 값을 가진다.
- key
atom의 key와 동일하며 프로젝트 전체에서 고유한 문자열을 가져야 한다.- get
파생된 상태를 반환하는 곳이다.
get(countState) 처럼 countState를 get하고 있으면 countState가 바뀔 때마다 새로운 값을 리턴해준다.
get()을 여러번 사용 가능하고 그중 하나라도 변하게 되면 리렌더링된다.get: ({get}): number => { // countState를 구독하고 있습니다. // countState가 바뀔 때마다 1증가 시켜서 반환합니다. const count = get(countState); return count + 1; },
recoil을 사용하기 위해서는 사용하고자하는 부모 컴포넌트에다 를 사용해야합니다.
보통 전역적으로 사용하기 때문에 루트 컴포넌트에 넣는게 좋다.// index.tsx import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import { RecoilRoot } from 'recoil'; ReactDOM.render( <React.StrictMode> <RecoilRoot> <App /> </RecoilRoot> </React.StrictMode>, document.getElementById('root') );
atom 혹은 selector의 값을 읽고 쓰려고 할 때 사용한다.
useState() 와 비슷한 형태로 생겼다. 다만 기본값 대신 recoil의 상태로 인자를 받습니다.
상태가 업데이트되면 자동적으로 리렌더링 일어난다.// useRecoilState const [count, setCount] = useRecoilState(countState); const increaseCount = () => { setCount(count + 1); }
사용법은 [get, set]으로 useState와 동일하다.
- selector의 경우 set을 설정해 주지 않았다면 사용하지 못한다.
set을 설정해야만 쓰기 가능한 상태로 바뀌기 때문이다. 그전까지는 읽기 전용 상태이다.
useRecoilState의 기능을 반으로 분리할 수 있습니다.
useRecoilValue
const setCount = useSetRecoilState(countState);
Recoil 상태의 값을 업데이트하기 위한 setter 함수를 반환한다.
이 hook 은 상태를 읽지 않고 쓰기만 하고 싶을 때 추천한다.useSetRecoilState
const setCount = useSetRecoilState(countState);
Recoil 상태의 값을 업데이트하기 위한 setter 함수를 반환한다.
이 hook 은 상태를 읽지 않고 쓰기만 하고 싶을 때 추천한다.useResetRecoilState
atom이나 selector의 값을 초기화하고 싶을 때 사용한다.
const resetCount = useResetRecoilState(countState); ... <button onClick={resetCount}>reset count</button>
참조
어렵다.