Suspense는 비동기를 동기처럼 보이게 만든다. 데이터가 아직 없으면 promise를 던지고, React가 그걸 받아 기다렸다가 다시 그린다. 그래서 상태를 조율하는 대신 입력을 미루고 → 질의하고 → 그리는 순서로 끝난다.
언제: 비동기 데이터를 그리는데 로딩·에러가 늘면서 화면이 튈 때. 또는 새로 만들면서 어느 쪽으로 갈지 고를 때.
절차
- 검색어·결과·로딩 중인지·에러인지를 각각 들고 있는지 본다. 넷이 따로 켜지고 꺼지니 실제로는 있을 수 없는 조합까지 코드가 표현할 수 있다 — “로딩 중이면서 동시에 에러” 같은 것. 그 조합이 한 프레임이라도 그려지면 화면이 튄다.
- 분기를
if/else에서 트리로 옮긴다 — 로딩은<Suspense>, 에러는<ErrorBoundary>, 성공은 본문. - 본문에 loading·error를 인자로 넘기지 않는다. 안 넘겨도 가장 가까운 경계가 대신 잡기 때문이다 —
render는 결과 하나만 받는다.
확인: 있을 수 없는 조합을 적을 수 있는가. 적을 수 없으면 된 것이다 — 상태가 로딩이거나, 에러거나, 성공이거나 셋 중 하나가 된다.
함정: 스피너가 너무 빨리 뜨고 사라지는 건 이 축으로 안 고쳐진다 — 다른 축이다 → 573
곁가지 — 인자를 위로 들어올려 바깥이 처리하게 하는 이 모양은 대수적 효과(algebraic effects)의 handler와 같다.1
stale-while-revalidate(두 시계·isStale) 부분은 570으로.
Footnotes
-
try/catch와 비슷하다 — 중간 함수들은 몰라도 되고 가장 가까운 handler가 받는다. 다른 점은 처리하고 끝나지 않는다는 것이다. handler가 값을 돌려주면 효과를 일으킨 자리로 되돌아가 실행이 이어진다. (Algebraic Effects for the Rest of Us) ↩