Selector는 atom의 output을 변형시키는 도구이다.
atom은 배열만 줄뿐, 그 output을 변형시키는 것은 selector이다. 하지만 state자체가 변하는것은 아니다.
useRecoilValue를 사용하여 atom의 output도 얻을 수 있고 selector의 output도 얻을 수 있다.
seletor에는 key가 있고 get이라는 메소드가 있다.
get은 options이라는 객체 인자를 받으면서 호출되는데, 그 객체에 get 함수가 들어있다. 그 get 함수를 이용하면 selector의 내부로 atom을 가져올 수 있는것이다.
import { atom, selector } from "recoil";
export interface IToDo {
id: number;
text: string;
category: "TO_DO" | "DOING" | "DONE";
}
export const toDoState = atom<IToDo[]>({
key: "toDo",
default: [],
});
export const toDoSelector = selector({
key: "toDoSeletor",
get: ({ get }) => {
const toDos = get(toDoState);
return [
toDos.filter((toDo) => toDo.category === "TO_DO"),
toDos.filter((toDo) => toDo.category === "DOING"),
toDos.filter((toDo) => toDo.category === "DONE"),
];
},
});
key 밑의 get함수는 selector가 어떤 것을 반환할지를 결정한다. get함수는 인자로 객체를 받는데, 이 객체에는 또 다른 get 함수가 들어있고 이 함수를 쓰면 원하는 atom을 가져올 수 있다.
위와 같이 원래는 배열에 모든 값이 들어있었다면 selector를 사용하여 그 값을 나눌 수 있다.
atom에 데이터를 모아두고 selector로 변형한다고 생각하면 쉽다.
selector 함수에는 set이라는 속성도 있다.
set은 atom을 수정하는 것을 도와준다. set함수도 첫번째 인자로 option이라는 객체를 주는데, 그 안에 setRecoilState를 갖고있다.
//atom.tsx
export const hourSelector = selector<number>({
key: "hours",
get: ({ get }) => {
const minutes = get(minuteState);
return minutes / 60;
},
set: ({ set }, newValue) => {
const minutes = Number(newValue) * 60;
set(minuteState, minutes);
},
})
//App.tsx
const [hours, setHours] = useRecoilState(hourSelector);
const onHourChange = (event: React.FormEvent<HTMLInputElement>{
setHours(+event.currentTarget.value);
}