Suspense는 비동기를 동기처럼 보이게 만든다. 데이터가 아직 없으면 promise를 던지고, React가 그걸 받아 기다렸다가 다시 그린다. 그래서 상태를 조율하는 대신 입력을 미루고 → 질의하고 → 그리는 순서로 끝난다.

직접 만들면 넷을 따로 들고 있어야 한다 — 검색어, 결과, 로딩 중인지, 에러인지. 넷이 각각 켜지고 꺼지니 실제로는 있을 수 없는 조합까지 코드가 표현할 수 있다. “로딩 중이면서 동시에 에러” 같은 것. 그 조합이 한 프레임이라도 그려지면 화면이 튄다. (스피너가 너무 빨리 뜨고 사라지는 쪽은 다른 축 — 573)

선언적으로 쓰면 상태가 셋 중 하나가 된다 — 로딩이거나, 에러거나, 성공이거나. 있을 수 없는 조합은 아예 적을 수가 없다.

분기도 if/else가 아니라 트리가 맡는다. 로딩은 <Suspense>, 에러는 <ErrorBoundary>, 성공은 본문.

그래서 render가 가벼워진다. loading·error를 인자로 넘길 필요가 없다 — 안 넘겨도 가장 가까운 경계가 대신 잡기 때문이다. render는 결과 하나만 받는다.


곁가지 — 인자를 위로 들어올려 바깥이 처리하게 하는 이 모양은 대수적 효과(algebraic effects)의 handler와 같다.1

stale-while-revalidate(두 시계·isStale) 부분은 570으로.

Footnotes

  1. try/catch와 비슷하다 — 중간 함수들은 몰라도 되고 가장 가까운 handler가 받는다. 다른 점은 처리하고 끝나지 않는다는 것이다. handler가 값을 돌려주면 효과를 일으킨 자리로 되돌아가 실행이 이어진다. (Algebraic Effects for the Rest of Us)

#575