Sonic UIv0.6.2

할 일 목록

JSONPlaceholder의 할 일 200개를 필터, DataGrid, Pagination으로 보여 주고, 하네스 규칙대로 레이어를 나눈 사례예요.

화면

필터와 페이지는 URL에 남아서 새로고침하거나 링크를 보내도 같은 화면이 나와요.

할 일

사용자, 상태, 검색어로 골라 봐요.
사용자상태

4가지 상태

정상은 위 화면이에요. 필터 줄은 그대로 두고 표 자리만 바꾸고, 빈 상태와 에러에서는 Pagination을 숨겨요.

로딩 · 처음 불러올 때 같은 배치에 자리만 표시
사용자상태
빈 상태 · 조건에 맞는 할 일이 없을 때
사용자상태

조건에 맞는 할 일이 없어요

검색어를 지우거나 다른 사용자를 골라 보세요.

에러 · 불러오지 못했을 때
사용자상태

코드 구조

조회는 entities, 둘을 합치는 건 widgets, URL 상태와 Suspense·ErrorBoundary는 pages가 맡아요. 필터 값은 URL에서 API 쿼리로 그대로 바뀌어요.

text
src/
├─ entities/todo/       model · api(todo.api · todo.queries · todo.mock) · hooks
├─ entities/user/       api(user.queries · user.mock) · hooks
├─ widgets/todo-grid/   ui/todo-grid.tsx  ← todo와 user를 합쳐 DataGrid에 넘겨요
├─ pages/case-studies/  model/use-todo-list-search-params.ts  (nuqs)
│                       ui/todos-page.tsx  (prefetch · Suspense · ErrorBoundary)
└─ app/mocks/handlers.ts  todoHandlers · userHandlers

todoQueries.list(params) → useSuspenseQuery → <DataGrid rowCount={total} />
URL필터API 쿼리
q=quis검색 Inputq=quis
userId=3사용자 SelectuserId=3
status=done상태 ToggleGroupcompleted=true
sort=title.desc머리글 정렬_sort=title&_order=desc
page=2&size=10Pagination_page=2&_limit=10

결정

  • 정렬과 페이지는 서버가 해요DataGrid에 rowCount를 넘겨 서버 모드로 써요. 받은 한 페이지만 정렬하면 전체 순서와 달라져요.
  • 필터를 바꾸면 1페이지로검색어, 사용자, 상태가 바뀌면 page를 1로 되돌려요. 없는 페이지에 머무르지 않아요.
  • 페이지를 넘겨도 이전 화면을 유지해요새 조건은 useDeferredValue로 넘겨서, 불러오는 동안 이전 결과를 보여 줘요. Skeleton은 처음 불러올 때만 보여요.
  • 검색은 입력을 멈추고 300ms 뒤글자마다 요청하지 않도록 URL 갱신을 debounce해요.
  • 사용자 이름은 widget에서 합쳐요todo와 user는 서로 다른 entity라 서로 가져오지 않아요. 둘을 합치는 건 widgets/todo-grid예요.

쓴 컴포넌트

  • DataGrid
  • Pagination
  • Input
  • Select
  • ToggleGroup
  • Badge
  • Skeleton
  • EmptyState
  • ErrorState