[Error] useQuery 사용 시 에러가 발생할 때 : A component suspended while responding to syncronous input. This will cuase...
문제가 발생한 환경
- next.js 사용
- react 18 version
- react-query 사용
- 하나의 페이지에서 탭으로 여러개의 컴포넌트를 왔다갔다 하며 query가 실행될 때 에러 발생.
에러메세지
- A component suspended while responding to syncronous input. This will cuase...어쩌구
컴포넌트 모양과 에러 내용
return (
<ErrorBoundary FallbackComponent={<ErrorFallback />}>
<Container>
<TapMenu menu={menu} setMenu={setMenu} />
{menu === 'MYPROFILE' ? (
<MyProfile />
) :
menu === 'MYORDER' ? (
<MyOrder />
) : null
)}
</Container>
</ErrorBoundary>
)
대략 이렇게 생긴 tap메뉴가 있는 화면에서, 현재 랜딩 된 tap 컴포넌트에서 다른 tap을 눌러 다른 컴포넌트를 렌더하면 위의 에러가 발생했다.
원인 : useQuery에서 suspense를 true로 줘 놓고 컴포넌트를 Suspense로 감싸지 않았음.
- useQuery의 옵션 중 react 18의 suspense기능을 사용하겠다는 옵션을 줄 수 있다.
- 이것을 true로 줄 경우, 해당 useQuery를 호출하는 컴포넌트가 Suspense 컴포넌트로 감싸져있어야 한다.
- useQuery 코드
export const useGetProfile = (id: number, onSuccess: any) => {
return useQuery(['myProfile', id], () => getMyProfile(id), {
suspense: true, //==> true면, 해당 query를 호출하는 컴포넌트를 suspense로 감싸줘야 함
retry: false,
refetchOnWindowFocus: false,
keepPreviousData: true,
enabled: id !== null,
onSuccess: (data) => onSuccess(data),
})
}
해결
- react에서 제공하는 Suspense컴포넌트로 useQuery를 호출하고 있는 컴포넌트들을 감싸주었다.
- Suspense의 fallback props에는 무엇이든 useQuery가 process중일 때 보여줄 컴포넌트를 넣어주면 된다.
- useQuery에서 suspense옵션을 주지 않거나 false로 해두면 이러한 처리를 해주지 않아도 된다.
- 하지만 suspense기능을 사용한다면 사용자에게 현재 데이터가 로딩중이라는 사실을 알려줄 수 있어 UX향상에 도움이 된다.
return (
<ErrorBoundary FallbackComponent={<ErrorFallback />}>
<Container>
<TapMenu menu={menu} setMenu={setMenu} />
{menu === 'MYPROFILE' ? (
<Suspense fallback={<Loading />}> {/* 요거 */}
<MyProfile />
</Suspense>
) :
menu === 'MYORDER' ? (
<Suspense fallback={<Loading />}> {/* 요거 */}
<MyOrder />
</Suspense>
) : null
)}
</Container>
</ErrorBoundary>
)
이걸로 삽질 3시간 냠냠. 처음엔 랜덤하게 발생하는 에러인줄 알았다. (당연히 그럴 리가 없는데 행복회로를 돌렸던듯..)
에러가 발생한 코드 위치에는 문제의 소지가 없어보였고, 에러메시지는 무슨 뜻인지 이해 못함.
내가 저 옵션을 줘 놓고 Suspense 컴포넌트로 감싸는걸 까먹고 멀정한 코드 계속 수정해고 바꿔보고
내가 queryKey를 잘못 줬나 수십번 확인하고 흑흑. 그래도 해결되니까 몇시간 삽질했는지는 중요치 않고 그냥 기분 좋음.
이것이 개미지옥 개발의 매력.
'프론트엔드' 카테고리의 다른 글
[React] 클라이언트에서 pagination 구현하기 2. (복잡버전) (0) | 2022.09.27 |
---|---|
[React] 클라이언트에서 pagination 구현하기 1. (심플버전) (0) | 2022.09.27 |
[HTML] WAI-ARIA : 웹 접근성에 대한 표준 기술 규격을 제공하는 웹앱 (0) | 2022.09.17 |
[HTML] 웹페이지 접근성 향상시키기 (1) | 2022.09.17 |
[HTML] 당신이 몰랐을 수도 있는 시맨틱 태그들 텍스트 편 (0) | 2022.09.17 |