export const toDoSelector = selector({
key: "toDoSelector",
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"),]
}
})
Selector represents a piece of derived state -> (state를 입력받아서 그걸 변형해 반환하는 순수함수를 거쳐 반환된 값)
the point of selector is that atom을 가져다가 output을 변형할 수 있다는 것, get function이 있어야 atom을 받을 수 있음
배열 안의 배열을 선택하려면 배열을 열고 순서대로 이름을 정하면 됨
const [toDo, doing, done] = useRecoilValue(toDoSelector);
function ToDoList() {
const [toDo, doing, done] = useRecoilValue(toDoSelector);
return (
<div>
<h1>To Dos</h1>
<hr />
<CreateToDo />
<h2>To Do</h2>
<ul>
{toDo.map(toDo => <ToDo key={toDo.id} {...toDo} />)}
</ul>
<hr />
<h2>Doing</h2>
<ul>
{doing.map(toDo => <ToDo key={toDo.id} {...toDo} />)}
</ul>
<hr />
<h2>Done</h2>
<ul>
{done.map(toDo => <ToDo key={toDo.id} {...toDo} />)}
</ul>
</div>
)
}
export default ToDoList;
toDoState 배열에 값을 추가하는 것은 여전하지만, 그 아톰으로 부터 값을 불러 오지 않음.
now we're getting our value from the selector which gets the atom and transform the atom.
<Select 만들어 선택한 카테고리에 해당하는 항목만 보도록 refactoring>
// handle category the user is currently selecting
export const categoryState = atom({
key: "category",
default: "TO_DO"
})
아래
{category === "TO_DO" && toDo.map((aToDo) => <ToDo key={aToDo.id} {...aToDo} />)}
{category === "DOING" && doing.map((aToDo) => <ToDo key={aToDo.id} {...aToDo} />)}
{category === "DONE" && done.map((aToDo) => <ToDo key={aToDo.id} {...aToDo} />)}
가능 하지만, 최선이 아니라고 한다.
Then..? => selector 이용.
export const toDoSelector = selector({
key: "toDoSelector",
get: ({ get }) => {
const toDos = get(toDoState);
const category = get(categoryState);
if (category === "TO_DO") return toDos.filter((toDo) => toDo.category === "TO_DO")
if (category === "DOING") return toDos.filter((toDo) => toDo.category === "DOING")
if (category === "DONE") return toDos.filter((toDo) => toDo.category === "DONE")
}
})
function ToDoList() {
const toDos = useRecoilValue(toDoSelector);
const [category, setCategory] = useRecoilState(categoryState)
const onInput = (event: React.FormEvent<HTMLSelectElement>) => {
setCategory(event.currentTarget.value)
}
console.log(category)
return (
<div>
<h1>To Dos</h1>
<hr />
<select value={category} onInput={onInput}>
<option value="TO_DO">To Do</option>
<option value="DOING">Doing</option>
<option value="DONE">Done</option>
</select>
<CreateToDo />
{toDos?.map(toDo => <ToDo key={toDo.id} {...toDo} />)}
</div>
)
}
selector 최종
export const toDoSelector = selector({
key: "toDoSelector",
get: ({ get }) => {
const toDos = get(toDoState);
const category = get(categoryState);
return toDos.filter((toDo) => toDo.category === category)
}
})
enum (0,1,2,...)
export enum Categories {
"TO_DO",
"DOING",
"DONE"
}
또는
export enum Categories {
"TO_DO" = "TO_DO",
"DOING" = "DOING",
"DONE" = "DONE"
}
이와같이 표현 가능