when?
일반적인 경우 우리는 상태가 업데이트 되었을 때, 이것이 화면에 즉시 반영되길 원한다.
하지만 업데이트가 화면에 반영되는 것을 연기해야할 때도 존재할 수 있다.
ex) 한 페이지에서 다른 페이지로 이동 시, 다음 화면에 표시될 데이터가 load되지 않았을 경우
→ 바로 다음 페이지로 넘어가기보다, 이전 화면에 오래 머무는 것이 더 나은 사용자 경험
(이러한 패턴 구현이 이전 React에서는 쉽지 않았다고 한다)
React 18의 Concurrent mode → 이를 위한 새로운 tools 제공!
useTransition hooks
1. 실제로 Concurrent 모드를 사용하고 있는지 확인
- 해당 Concurrent 모드 동작을 위해 ReactDOM.createRoot()보다, ReactDOM.render()를 사용
const rootElement = document.getElementById("root");
// Opt into Concurrent Mode
ReactDOM.createRoot(rootElement).render(<App />);
2. useTransition 사용
const [isPending, startTransition] = useTransition();
useTransition은 isPending, startTransition이란 두가지 값을 return
1) isPending
- boolean
- transition이 진행 중인지 여부
2) startTransition
- 연기하려는 상태 업데이트 로직을 React에 전달
사용 예시
setState를 transition 내 wrapping
// 해당 상태 업데이트 로직을
<button
onClick={() => {
const nextUserId = getNextId(resource.userId);
setResource(fetchProfileData(nextUserId));
}}
>
// transition으로 감싸기!
<button
onClick={() => {
startTransition(() => {
const nextUserId = getNextId(resource.userId);
setResource(fetchProfileData(nextUserId));
});
}}
>
→ 이를 통해 React에게 해당 업데이트가 바람직하지 않은 로딩 상태로 이어질 경우, 이를 지연해도 상관 없음을 알려줄 수 있다
pending 상태 제어
but 상태 업데이트 지연 시, 앱이 아무런 동작을 하지 않는 것처럼 보이는 것 역시 사용성 저하↑
isPending을 통해 현재 transition 종료를 대기 중인지 판단O
Where Does the Update Happen?
이 때 상태 업데이트는 어떻게 이뤄지는걸까?
지연 작업이 진행 중일 때(isPending이 true) → 현재 우리가 보고 있는 컴포넌트 버전
상태 업데이트 완료 → 우리가 완료되길 기다리고 있는 컴포넌트 버전
☞ 즉 하나의 컴포넌트에 두가지 버전이 존재하는 상황!
- 이것이 Concurrent mode의 핵심!
Another way we can conceptualize is that wrapping a state update in startTransition begins rendering it “in a different universe”, much like in science fiction movies. We don’t “see” that universe directly — but we can get a signal from it that tells us something is happening (isPending)
- '다른 우주'에서 startTransition를 렌더링하고, 우리는 그 우주를 직접 볼 수는 없지만 무언가가 일어나고 있음을 알려주는 신호(isPending)는 전달받을 수 있다
- 즉 실제로 두개의 컴포넌트가 동시에 존재하지는 않지만(그럴 수도 없고), React가 화면에 표시되는 트리 버전과 다음에 표시할 "준비" 중인 버전을 전환해가며 화면을 그려주는 것!
'source-code > React' 카테고리의 다른 글
React Query - keepPreviousData (0) | 2023.08.15 |
---|---|
useReducer (0) | 2023.08.15 |
patch-package 사용하기 (0) | 2021.05.24 |
CRA에 Next.js 적용하기 3 (0) | 2021.05.14 |
CRA에 Next.js 적용하기 2 (0) | 2021.05.13 |