JBEE.io
JBEE.io copied to clipboard
react/error-declarative-handling-1/
React에서 선언적으로 비동기 다루기 | JBEE.io
에러를 효율적으로 다루기 위해 선언적으로 에러를 정의하고 처리하는 방법을 고민했고 그 결과물을 공유합니다. Suspense와 ErrorBoundary를 사용하여 비동기 컴포넌트를 보다 효율적으로 처리하는 컴포넌트를 소개합니다. Table of Contents 명령형으로 처리하기 선언형으로 처리하기 Suspense ErrorBoundary 비동
좋은 글 시리즈 고맙습니다. 이전에 대강 비슷한 고민을 하다가 포기했었는데, 시리즈를 읽으면서 다시 깊게 고민해보게 되네요.
그런데 Suspense
와 데이터 페칭을 같이 사용하려면 리액트를 experimental 버전으로 사용해야 하는 것으로 알고 있는데 프로덕션에서 그렇게 사용해도 괜찮을까요?
그리고 마무리 단락에 수정이 덜 된 부분이 있어서 제보드립니다.
Suspense와 ErrorBoundary를 적절히 조합하여 비동기 컴포넌트를 "다루기 위한 만들어봤는데" 사용자 경험 입장에서도 개발 생산성에서도 좋은 효과를 보이고 있다.
@adhrinae 가뭄에 단비같은 댓글 감사합니다 ㅎㅎ (수정이 필요한 부분도 제보 감사해요~)
결론부터 말씀드리자면 Production에서 (아직) 문제없이 사용하고 있습니다!ㅎㅎ
그리고 이 포스팅을 공개하겠다고 마음먹은 것은 https://github.com/facebook/react/issues/13206#issuecomment-805480060 요 코멘트 때문인데요,
We see the light at the end of the tunnel. This time it’s closer. 🙂 Hang on.
라고 하네요 ㅎㅎ
안녕하세요 글 잘보았습니다 :)
SSRSafeSuspense
내부에서 클라이언트와 서버를 분기할때
const isServer = typeof window === "undefined";
와 같은 값으로 분기를 나누지 않고 mounted state 를 선언하여 사용하신 이유가 궁금합니다 :)
@appear 지인 제보를 통해 comment가 달린 것을 알았네요 ㅠㅠ Hydration 이슈 때문에 저렇게 해주었어요 ㅎㅎ 이상 늦은 답변입니다.
좋은 글 감사합니다. :-) 이번에 토이하면서 적용해봤는데, 확실히 data fetching 전후 렌더링 제어나 에러 핸들링이 선언적으로 되니까 명시적이고 깔끔하네요!
좋은 글이 많네요 (이글 포함) 정보 공유에 행복해서 몸둘바를 모르겠슴다
안녕하세요. 좋은 글 감사합니다. 선언적인 비동기 처리를 적용해보면서 고민됐던 지점이 있어 댓글 남깁니다. 컴포넌트에 필요한 데이터를 패치하는 경우에는 선언적으로 코드를 짜기 좋았는데요. 몇몇 경우 불필요하거나, 어렵다고 느낄 때가 있었어요. 예를 들어, 유저가 버튼을 클릭했을 때 이벤트 핸들러에서 서버로 인증을 요청해서 그 결과에 따라 분기(페이지 이동 등)를 나누는 경우에요. swr, react query 같은 선언적 비동기 처리를 권장하는 쿼리 라이브러리로 코드를 깔끔히 짜는게 어려웠습니다. 혹시 jbee 님께서는 이런 케이스가 있으셨는지, 있으셨다면 어떤 식으로 처리하셨는지 궁금합니다.
인사이트 많이 얻고 갑니다. 좋은 정보 공유해주셔서 감사합니다.
@seung-00 님 답변이 늦었습니다.
유저가 버튼을 클릭했을 때 이벤트 핸들러에서 서버로 인증을 요청해서 그 결과에 따라 분기(페이지 이동 등)를 나누는 경우
말씀해주신 이 경우가 명령형으로 흐름이 진행되는 것 같은데, 선언적으로 수정해보면 어떨까요? 예를 들면 다음과 같은 플로우입니다.
- 버튼을 클릭했을 때 어떤 값을 수정한다. 또는 어떤 임의의 페이지로 이동하거나 동작을 한다.
- 그 값의 변경에 따라 서버로 인증을 요청하고 어떤 어떤 처리를 진행한다.
핵심은 버튼은 페이지 이동 등 뒤에 발생하는 분기를 모른다는 점입니다.
토스 SLASH 22 영상을 보고, 블로그에 방문했는데 좋은 글까지 너무 감사합니다! 😀
function Main() {
return (
<main>
<Suspense fallback={<Loading />}>
<UserDropDown />
</Suspense>
</main>
)
}
function UserDropDown() {
const { data: user } = useUser()
return <div>{user.name}</div>
}
여기서 보면 user가 User | undefined
type이 나오지 않나요??
useQuery에 suspense: true
을 주어도 data가 undefined가 나오는건 어떻게 처리하셨는지 궁금합니다
@kyujonglee 님 안녕하세요,
useQuery에 suspense: true을 주어도 data가 undefined가 나오는건 어떻게 처리하셨는지 궁금합니다
tsserver로 infer되는 타입과 실제 할당될 수 있는 값의 형태는 다를 수 있습니다.
useQuery에 suspense: true
를 전달해줘도 기대한대로 type이 infer되지 않는데요,
그 이유는 해당 suspended query를 Suspense
컴포넌트 내에서 호출될지는 결정하지 않았기 때문입니다.
저는 suspended query를 Suspense
없이 사용하게 되면 컴파일 단계에서 에러가 발생하기 때문에
타입 충분히 단언해도 된다고 판단했고 react-query를 한번 wrapping해서 타입을 오버라이드 하여 사용하고 있습니다.
안녕하세요 jbee님의 글을 보고 Next.js로 에러 핸들링하는 것에 정말 많은 도움이 돼서 먼저 감사의 인사를 드리고 싶습니다! 다름이 아니라 제가 한 가지 문제점에 봉착했는데요! Suspense
를 사용하면 Loading fallback
이 나타나야 하는데 나타나지 않아서 고민을 했었습니다. 결론은 dynamic import
를 통해 해결했는데요 한 가지 의문점은 Suspense를 사용하려면 dynamic
을 반드시 사용해야 하는지에 대한 의문입니다. jbee님도 dynamic을 사용하셨는지 여쭙고 싶습니다! 사용하지 않으셨다면 어떻게 해결하셨는지 여쭙고 싶습니다!
@kingyong9169 Suspense
하위 컴포넌트들이 suspended 상태에 놓여야 할텐데요, 이 부분에 대해 살펴보시면 도움이 될 것 같습니다 :)
@JaeYeopHan 좋은 답변해주셔서 정말 감사합니다ㅎㅎ 좋은 하루 되세요!
안녕하세요 좋은 글 감사합니다! ErrorBoundary의 경우 에러 발생시 기존 컴포넌트를 fallback으로 대체하고 있는데요. 기존 컴포넌트 위에 토스트메세지나 모달을 띄우거나 인라인 메세지를 노출하는 방식으로 에러처리를 하는경우도 많을 것 같은데 이런 경우 선언적으로 어떻게 처리하고 계신지 궁금합니다!
@kyujonglee 님 재엽님의 댓글에 나오는 react-query를 한 번 wrappinng한 hook이 이번에 오픈소스로 공개한 @toss/react-query의 useSuspenedQuery와 비슷한 형태일 거 같아서 참고하면 좋을 거 같아요 참고로 이 훅은 react-query v3를 wrapping하고 있어요 사용에 참고 부탁드려요