# Selectors Selector는 상태를 가져와 보여줍니다. 가져온 상태는 최신 상태입니다. 가져온 상태는 어떤 주어진 상태를 수정하는 순수한 함수에 상태를 전달한 결과로 생각할 수 있습니다. selector를 이용하여 가져온 상태는 다른 데잉터에 의해 의존하는 동적 데이터를 구축할 수 있습니다. 여기서 selector로 가져온 상태를 파생된 상태(derived state)라고 합니다. 할 일 목록 애플리케이션에서 다음을 파생된 상태로 취급합니다. * Filtered Todo List: 필터링 한 데이터 파생 * Todo list statistics: 목록의 총 항목 수, 완료된 항목 수, 백분율과 같은 통계 데이터 파생 할일 목록을 필터링하기 위해 값을 아톰에 저장 할 수 있는 필터 기준을 선택해야 합니다. 여기서 사용할 필터 옵션은 모두 표시, 완료 표시, 미완료 표시 입니다. 기본값은 모두 표시입니다. ```js const todoListFilterState = atom({ key: 'todoListFilterState', default: 'Show All', }); ``` `todoListFilterState` 및 `todoListState`를 사용하여 필터링 된 목록을 파생시키는 `filtersTodoListState` 선택기를 작성할 수 있습니다. ```js const filteredTodoListState = selector({ key: 'filteredTodoListState', get: ({get}) => { const filter = get(todoListFilterState); const list = get(todoListState); switch (filter) { case 'Show Completed': return list.filter((item) => item.isComplete); case 'Show Uncompleted': return list.filter((item) => !item.isComplete); default: return list; } }, }); ``` filteredTodoListState는 todoListFilterState와 todoListState 중 하나라도 변경되면 다시 실행합니다. 필터링 된 todoList를 표시하기 위해 TodoList 컴포넌트에서 주석처리 된 TodoListStats와 TodoListFilters 컴포넌트 주석을 해제합니다. ```jsx function TodoList() { const todoList = useRecoilValue(todoListState); return ( <> {todoList.map((todoItem) => ( ))} ); } ``` 필터 변경을 이용해 todoListFilters 컴포넌트를 구현합니다. ```jsx function TodoListFilters() { const [filter, setFilter] = useRecoilState(todoListFilterState); const updateFilter = ({target: {value}}) => { setFilter(value); }; return ( <> Filter: ); } ``` 짧은 줄로 필터링 컴포넌트를 구현했습니다. 동일한 개념을 사용하여 `TodoListStats` 구성 요소를 구현합니다. 표시할 통계항목은 다음과 같습니다. * 할 일 항목의 총 수 * 완료된 항목 수 * 완료되지 않은 항목의 총 수 * 완료된 항목의 백분율 각 통계에 대해 selector를 만들 수 있지만 필요한 데이터가 포함된 객체를 반환하는 하나의 선택기를 만들 수 있습니다. 여기서는 selector를 todoListStatsState로 구현합니다. ```js const todoListStatsState = selector({ key: 'todoListStatsState', get: ({get}) => { const todoList = get(filteredTodoListState); const totalNum = todoList.length; const totalCompletedNum = todoList.filter((item) => item.isComplete).length; const totalUncompletedNum = totalNum - totalCompletedNum; const percentCompleted = totalNum === 0 ? 0 : totalCompletedNum / totalNum; return { totalNum, totalCompletedNum, totalUncompletedNum, percentCompleted, }; }, }); ``` `todoListStatsState` 의 값을 읽기 위해 useRecoilValue()를 사용합니다. ```jsx function TodoListStats() { const { totalNum, totalCompletedNum, totalUncompletedNum, percentCompleted, } = useRecoilValue(todoListStatsState); const formattedPercentCompleted = Math.round(percentCompleted * 100); return (
  • Total items: {totalNum}
  • Items completed: {totalCompletedNum}
  • Items not completed: {totalUncompletedNum}
  • Percent completed: {formattedPercentCompleted}
); } ``` 지금까지 구현된 할 일 목록 애플리케이션 기능 목록은 다음과 같습니다. * 할 일 추가 * 할 일 수정 * 할 일 삭제 * 필터 * 통계 다음 섹션에서 중요한 고려사항을 다룹니다.