//atom 함수를 사용해서 생성
const fontSizeState = atom({
key: 'fontSizeState',
default: 14,
})
const fontSizeLabelState = selector({
key: 'fontSizeLabelState',
//get속성은 계산될 함수
get: ({get}) => {
const fontSize = get(fontSizeState);
const unit = 'px';
return `${fontSize}${unit}`;
},
});
const FontButton = () => {
const [fontSize, setFontSize] = useRecoilState(fontSizeState);
const fontSizeLabel = useRecoilValue(fontSizeLabelState);
return (
<>
<div> font Size: ${fontSizeLabel}</div>
<button onClick={() => setFontSize((size) => size + 1)} style={{fontSize}}>
Enter
</button>
</>
);
}
부모트리에 <RecoilRoot></RecoilRoot>
로 감싸준다
<RecoilRoot>
의 원자 상태를 초기화하는 옵션 함수useSetRecoilState()
또는 useRecoilCallback()
과 같은 훅을 사용한다<RecoilRoot>
가 다른 <RecoilRoot>
와 중첩(nested)된 경우에만 상관이 있다.<RecoilRoot>
는 단지 자식 렌더링 외에 다른 기능을 수행하지 않기 때문에, 이 루트의 자식들은 가장 가까운 조상인 RecoilRoot의 Recoil값에 엑세스 할 것여러
<RecoilRoot>
를 사용하는 경우
<RecoilRoot>
는 여러개가 같이 존재할 수 있고, 각각이 독립적인 atom상태의 providers/store이 된다.- atom은 각 루트에 따라 다른 값을 갖게 되는 것이다.
- 그리고 이러한 동작은 override를 false로 지정하지 않는 한, 루트가 다른 루트에 중첩될 때(내부루트가 외부 루트를 가릴 경우)동일하게 발생 된다.
예시
function MyApp({ Component, pageProps: { ...pageProps }, authInfo }: MyAppProps) { const initializer = useMemo( () => async ({ set }: MutableSnapshot) => { if (authInfo) { set(authState, authInfo) setTokenAxios(authInfo.access, authInfo.refresh) } }, [authInfo], ) return( <RecoilRoot initializeState={initializer}> <Component {...pageProps}/> </RecoilRoot> )}
import { RecoilRoot } from 'recoil';
<RecoilRoot>
<Component {...pageProps} />
</RecoilRoot>
```
import { useRecoilState, useResetRecoilState } from "recoil";
import { userInfo } from "../stores/accounts";
const [info, setInfo] = useRecoilState(userInfo);
const resetInfo = useResetRecoilState(userInfo);
function TodoItem({item}) {
const [todoList, setTodoList] = useRecoilState(todoListState);
const index = todoList.findIndex((listItem) => listItem === item);
const editItemText = ({target: {value}}) => {
const newList = replaceItemAtIndex(todoList, index, {
...item,
text: value,
});
setTodoList(newList);
};
const toggleItemCompletion = () => {
const newList = replaceItemAtIndex(todoList, index, {
...item,
isComplete: !item.isComplete,
});
setTodoList(newList);
};
const deleteItem = () => {
const newList = removeItemAtIndex(todoList, index);
setTodoList(newList);
};
return (
<div>
<input type="text" value={item.text} onChange={editItemText} />
<input
type="checkbox"
checked={item.isComplete}
onChange={toggleItemCompletion}
/>
<button onClick={deleteItem}>X</button>
</div>
);
}
function replaceItemAtIndex(arr, index, newValue) {
return [...arr.slice(0, index), newValue, ...arr.slice(index + 1)];
}
function removeItemAtIndex(arr, index) {
return [...arr.slice(0, index), ...arr.slice(index + 1)];
}