Todo 앱은 하나의 원본 상태와 파생 화면으로 움직인다

목록 자체만 state로 두고 개수와 필터 결과는 렌더 중 계산하면 상태가 서로 어긋나지 않는다.

todos[] + filter앱의 최소 원본 상태
ADD

항목 추가

새 id와 text를 가진 todo 생성

TOGGLE

완료 전환

선택한 id의 completed만 반전

REMOVE

항목 삭제

선택한 id를 목록에서 제거

FILTER

보기 변경

all · active · done 중 하나 선택

핵심visibleTodos와 남은 개수는 todos와 filter에서 계산하는 파생값이며 별도 state가 아니다.