concurrentMode와 useTransition 활용

이준희·2023년 9월 13일
0

Concurrent Mode

JavaScript는 싱글 스레드 언어입니다. 이는 하나의 작업을 수행할 때 다른 작업을 동시에 수행할 수 없음을 의미합니다. 하지만 React에서 concurrent mode를 사용하면 여러 작업을 동시에 처리할 수 있습니다.

📌 concurrent mode를 사용하면 여러 작업을 동시에 처리 가능

React가 여러 작업을 동시에 처리하는 방식

React는 여러 작업을 작은 단위로 나눈 뒤, 그들 간의 우선순위를 정하고 그에 따라 작업을 번갈아 수행합니다. 서로 다른 작업들이 실제로 동시에 수행되는 것은 아니지만, 작업 간의 전환이 매우 빠르게 이루어지면서 동시에 수행되는 것처럼 보이게 되는 것입니다. 이를 동시성이라고 합니다.

이렇게 React는 동시성 개념을 도입해 싱글 스레드 환경에서 여러 작업을 동시에 할 수 있게 되었습니다.

Concurrent mode의 동작 원리

특정 state가 변경되었을 때 현 UI를 유지하고 해당 변경에 따른 UI 업데이트를 동시에 준비합니다. 준비 중인 UI의 렌더링 단계가 특정 조건에 부합하게 되면 실제 DOM에 반영하는 것이죠.

그래서 fallback으로 지정했던 컴포넌트를 띄우는 것이 아니라 현 UI를 유지하면서 변경을 준비합니다.

렌더링 단계


state 변경의 관점에서 보는 렌더링 관계는 위와 같이 3단계가 있습니다.

1. Transition 단계

Transition는 state 변경 직후에 일어날 수 있는 UI 렌더링 단계입니다.

Pending : useTransition 훅을 사용하면 state 변경 직후에 UI를 업데이트하지 않고 현 UI를 잠시 유지할 수 있는데 이를 Pending 상태라고 합니다.
Receded : useTransition 훅을 사용하지 않은 기본 상태. state 변경 직후 UI(Loader를 생각)가 변경됩니다.

그럼 Pending으로 걸어놨는데, 로딩 시간이 길어지면 UI에 안 좋은 거 아닌가?

→ Pending 상태에서도 Receded 상태로 넘어갈 수 있습니다! Pending 상태의 시간이 useTransition 옵션으로 지정된 timeoutMs를 넘으면 강제로 Receded 상태로 넘어갑니다.

const [isPending, startTransition] = useTransition({
    timeoutMs: 2000
  });

2. Loading 단계

현재 컴포넌트의 자식 요소에서 발생되는 비동기 처리하는 과정을 처리 중인 단계입니다. ex) Loader, SkeletionUI

3. Done 단계

비동기 처리가 완료됨에 따라 완성된 UI를 보여줍니다.

useTransition 활용법

위의 원리를 참고하여 Suspense를 사용한 리액트 코드내의 로딩 중 의미없는 깜빡임 이슈를 useTransition을 활용하여 해결할 수 있습니다.

  • isPending : 작업이 지연되고 있음을 알리는 boolean
  • startTransition : 낮은 우선순위로 실행할 함수를 인자로 받는다.
function App() {
  const [isPending, startTransition] = useTransition()
  const [page, setPage] = useState(1)
  
  const onNextPage = () => {
    startTransition(() => {
      setPage(prev => prev + 1)
    })
  }
  
  return (
    <Suspense fallback={<Loader />}>
      <Foo page={page} onNextPage={onNextPage} />
    </Suspense>
  )
}

function Foo({ page, onNextPage }) {
  return /* 성공했을 경우만 고려하여 작성 가능 */
}

useTranstion으로부터 나온 startTransition이라는 함수에 상태 업데이트 로직을 부여하면 해당 상태 업데이트로 인해 새롭게 발생하는 비동기 처리가 끝날 때까지 화면 렌더링 변화를 지연시킵니다. 정확히는 원래의 UI를 보여주다가 업데이트된 UI를 보여주는 형태입니다.

0개의 댓글