본문 바로가기
Libaray & Framework/ReactJS

Error: A component suspended while responding to synchronous input. This will cause the UI to be replaced with a loading indicator. To fix, updates that suspend should be wrapped with startTransition.

by mihyejeon 2024. 6. 25.

 react18 프로젝트에서 navigate 기능 구현 중에 다음과 같은 에러를 마주했다.

Error: A component suspended while responding to synchronous input. This will cause the UI to be replaced with a loading indicator. To fix, updates that suspend should be wrapped with startTransition.
'컴포넌트가 동기 입력에 응답하는 동안 suspend 되었고, 이로 인해 UI가 로딩 인디케이터로 교체되었습니다.
이 문제를 해결하려면 일지 정지된 업데이트를 startTransition으로 wrapping 해야합니다.

 

발생 원인

코드분할을 통해 초기 렌더링 지연시간을 줄이고자 React.lazy()로 컴포넌트를 동적으로 import 해오고 있었다.

그리고 중요한 점은, React.lazy()로 래핑된 컴포넌트는Suspense컴포넌트로 감싸져 있어야 한다.

하지만 나는 일부 Suspense를 빼먹고 말았다. (사실 말하기도 창피한 실수다)

Suspense는  React.lazy()로 생성된 비동기 컴포넌트가 로드되는 동안 로딩 화면과 같은 대체 컨텐츠를 보여줄 수 있게 해준다.

 

이전 코드

수정한 코드

const Layout = lazy(() => import('../components/Layout'));
const KTpaymentsystem = lazy(() => import('../pages/KTpaymentsystem'));
const LGpaymentsystem = lazy(() => import('../pages/LGpaymentsystem'));
const OpenCellPhone = lazy(() => import('../pages/OpenCellPhone'));
const Main = lazy(() => import('../pages/Main'));
const Chat = lazy(() => import('../pages/Chat'));

const router = createBrowserRouter([
  {
    path: '/',
    element: <Layout />,
    errorElement: <p>에러</p>,
    children: [
      {
        index: true,
        element: (
          <Suspense fallback={<p>Loading...</p>}>
            <Main />{' '}
          </Suspense>
        ),
      },
      {
        path: 'KTpaymentsystem',
        element: (
          <Suspense fallback="<p>Loading...</p>">
            {' '}
            <KTpaymentsystem />,
          </Suspense>
        ),
      },
      {
        path: 'LGpaymentsystem',
        element: (
          <Suspense fallback="<p>Loading...</p>">
            <LGpaymentsystem />
          </Suspense>
        ),
      },
      {
        path: 'open-cellphone',
        element: (
          <Suspense fallback="<p>Loading...</p>">
            <OpenCellPhone />
          </Suspense>
        ),
      },
      {
        path: 'chat',
        element: (
          <Suspense fallback="<p>Loading...</p>">
            {' '}
            <Chat />
          </Suspense>
        ),
      },
    ],
  },
]);

React.lazy() 함수로 반환된 컴포넌트가 로드되는 동안

Suspense 컴포넌트가 fallback prop으로 대체 컨텐츠를 정의하고 있다.

 

일단 fallback prop으로  'Loading...' 이라는 string을 바로 넣어주었지만 

추후 Fallback UI를 대체 컨텐츠로 넣을 생각이다