Recoil을 통해서 아톰(공유 스테이트)으로 부터 셀렉터(순수 함수)통해 흐르는 데이터-플로우 그래프를 생성할 수 있다. 아톰은 컴포넌트들이 참고할 상태(state)의 형태이다. 셀렉터는 이러한 상태(state)를 동기적으로 또는 비동기적으로 변형 시켜주는 역할을 한다.
상태의 형태(unit) 아톰은 업데이트가 가능하고, 참고할 수 있다. 아톰이 업데이트 될 때 마다 아톰을 참고하고있는 컴포넌트들이 새로운 밸류(value)값과 같이 re-render된다. 같은 아톰이 여러 컴포넌트에서 사용되면, 모든 컴포넌트들이 그들의 상태를 공유한다.
// usage
const fontSizeState = atom({
key: 'fontSizeState',
default: 14,
});
아톰은 고유한 키를 가진다. 이 키는 디버깅, 지속성, 그리고 특정 API에 사용 되어진다. 만약에 여러 아톰이 하나의 같은 키를 공유하면 에러를 발생하기 때문에 전역적으로 고유한 값을 가져야한다.
이 아톰을 사용하기위해서 useRecoilState라는 훅을 사용한다. useState와 비슷하지만, 컴포넌트끼리 공유가 가능하다.
function FontButton() {
const [fontSize, setFontSize] = useRecoilState(fontSizeState);
return (
<button onClick={() => setFontSize((size) => size + 1)} style={{fontSize}}>
Click to Enlarge
</button>
);
}
위와 아래처럼 fontSizeState를 공유할 수 있다.
function Text() {
const [fontSize, setFontSize] = useRecoilState(fontSizeState);
return <p style={{fontSize}}>This text will increase in size too.</p>;
}
셀렉터는 순수함수이고, 인풋으로 아톰이나 다른 셀렉터를 받는다. 아톰이나 셀렉터가 업데이트되면, 이 셀렉터 함수는 리-렌더를 한다. 컴포넌트들은 셀렉터를 참고하고, 셀렉터가 변경되면 재-렌더링을 실행한다.
셀렉터는 상태를 기반으로 한 추출된 데이터를 계산하는데 사용된다. 이렇게 함으로써 스테이트가 버려지는것을 피할 수 있다.(아톰은 최소한의 상태 형태이기때문이다.)
컴포넌트의 관전에서, 셀렉터와 아톰들은 같은 인터페이스를 가지고 서로를 대체할 수 있게 된다.
// usage
const fontSizeLabelState = selector({
key: 'fontSizeLabelState',
get: ({get}) => {
const fontSize = get(fontSizeState);
const unit = 'px';
return `${fontSize}${unit}`;
},
});