리액트의 한계
- 컴포넌트 상태는 상위요소까지 끌어 올려 공유될 수 있지만, 이 과정중 트리들이 다시 렌더링 되는 현상이 나타날 수 있음
- Context는 단일 값만 저장이 가능하며 consumer를 가지는 여러 값들의 집합을 담을 수 없음
- 위의 두가지 특성이 트리의 최상단(state 존재하는 곳)애서 트리의 잎(state 사용되는 곳)까지의 코드 분할이 어렵게함
//atom 함수 정의
const fontSizeState = atom({
key: 'fontSizeState',
default: 14,
});
function FontButton() {
const [fontSize, setFontSize] = useRecoilState(fontSizeState);
return (
<button onClick={() => setFontSize((size) => size + 1)} style={{fontSize}}>
Click to Enlarge
</button>
);
}
function Text() {
const [fontSize, setFontSize] = useRecoilState(fontSizeState);
return <p style={{fontSize}}>This text will increase in size too.</p>;
}
Selector: atoms 상태값을 동기적 혹은 비동기적으로 상태를 변환, atoms나 다른 selectors를 입력으로 받아들이는 순수 함수(pure function)
상위 atoms나 selectors가 업데이터되면 하위 selector함수도 다시 실행
컴포넌트들은 selectors를 atoms처럼 구독 가능하며, selectors가 변경되면 다른 컴포넌트도 다시 렌더링됨
상태를 기반으로 하는 파생데이터를 계산하는 데 사용.
자기자신의 필요와 자신의 어떤 상태의 의존하는지 추적을 하여 함수적인 접근방식을 효율적으로 만듬
컴포넌트 관점에서는 selectors와 atoms는 동일한 인터페이스를 가져 서로 대체 가능
//selector 함수 정의
const fontSizeLabelState = selector({
key: 'fontSizeLabelState',
get: ({get}) => { // get: 계산될 함수, 인자를 통해 atoms와 다른 selectors에 접근 가능
const fontSize = get(fontSizeState);
const unit = 'px';
return `${fontSize}${unit}`;
},
});
## 설치법
### NPM
`npm install recoil`
`yarn add recoil`
### Create React App
`npx create-react-app my-app`
### Recoil Package
`npm install recoil`
`yarn add recoil`
## RecoilRoot
- 루트 컴포넌트가 RecoilRoot를 넣기에 가장 좋은 장소
```js
import React from 'react';
import {
RecoilRoot,
atom,
selector,
useRecoilState,
useRecoilValue,
} from 'recoil';
function App() {
return (
<RecoilRoot>
<CharacterCounter />
</RecoilRoot>
);
}