Automatic Batching
batching
은 리액트 내부에서 더 나은 퍼포먼스를 위해, 다수의 상태값 업데이트가 이루어짐에도 불구하고 단 한번만 재렌더링이 이루어지도록 그룹화하여 일괄처리한다. 리액트 17버전까지는 event handler 함수 내부에서만batching
이 동작하고 있지만, 리액트 18버전부터는 프로미스 내부, setTimeout 등batching
이 이루어지지 않는 함수들에 default로 탑재가 된다.
// v17
const [count, setCount] = useState(0);
const [isChecked, setIsChecked] = useState(false);
useEffect(() => {
setTimeout(() => {
setCount(prev => prev + 1);
setIsChecked(prev => !prev);
// 렌더링이 두번 일어난다.
}, 1000);
}, []);
// v18
const [count, setCount] = useState(0);
const [isChecked, setIsChecked] = useState(false);
useEffect(() => {
setTimeout(() => {
setCount(prev => prev + 1);
setIsChecked(prev => !prev);
// 렌더링이 한번 발생한다.
}, 1000);
}, []);
- 만일
Automatic Batching
적용을 원하지 않을 경우,react-dom
에서 제공하는flushSync
를 사용함으로써batching
을 막을 수 있다.
// v18
import { flushSync } from 'react-dom';
// prevent batching
const [count, setCount] = useState(0);
const [isChecked, setIsChecked] = useState(false);
useEffect(() => {
setTimeout(() => {
flushSync(() => {
setCount(prev => prev + 1);
})
flushSync(() => {
setIsChecked(prev => !prev);
})
// 렌더링이 두번 발생한다.
}, 1000);
}, []);
Transitions
Transition
은, 리액트에서 긴급, 긴급하지 않은 상태 업데이트를 구분하는 새로운 콘셉트이다.- 긴급 업데이트: 상호작용(타이핑, 클릭, 누름 등)을 통해 상탯값이 즉각적으로 일어나는 것을 기대하는 상탯값들을 대상
- 전환 업데이트: 뷰의 전환, 즉 즉각적인 업데이트가 필요하지 않은 경우
- 즉, 기존에 사용자 경험을 개선하기 위해 사용했던
debounce
,throttle
,setTimeout
의 기능을 지원하는 내장 api가 추가되었다. useTransition
:startTransition
과 더불어 pending state를 추적할때 사용하는 hookstartTransition
: hook이 사용되지 않을때 Transitions을 사용하기 위한 메서드
Suspense, SSR
Suspense
를 사용하게 되면, date fetching
이 오래 걸리는 컴포넌트의 경우, 렌더링이 되기 전 로딩 상태를 지정할 수 있다. 즉 로딩 상태를 나타내는 또다른 상태값에 대한 의존을 해결하도록 도와준다.
- 기존의 SSR의 경우 해당 화면의 컴포넌트에서 HTML의 모든 요소들이 렌더된 후에
hydration
이 가능했지만,Suspense
를 통해서 컴포넌트를 선택적으로 렌더 및hydration
이 가능해졌다.- 기존 createRoot 대신 hyrdateRoot 사용
- 기존 리액트는
renderToString()
을 활용하여 HTML Streaming(Server에서 HTML 문서를 내려주는것)을 처리하였지만, 리액트 18버전부터pipeToNodeWritable()
를 활용해 HTML코드를 작은 청크로 나눈 후 보내줄 수 있기 때문에 선택적으로hydration
이 가능해졌다.
- 기존
SSR
에서hydration
을 위해서는 모든 HTML 요소들이 렌더링이 되어야hydration
아 가능했다.
Suspense
를 통해서 컴포넌트를 선택적으로 렌더 및hydration
이 가능해졌다.
<Layout>
<NavBar />
<Sidebar />
<RightPane>
<Post />
<Suspense fallback={<Spinner />}>
<Comments />
</Suspense>
</RightPane>
</Layout>
useTransition 이외 New Hooks
useId
- 고유한 ID값을 생성함으로써 클라이언트와 서버 사이의
hydration
미스매치를 피할 수 있다. - 콜론과 함께 생성되며 토큰이 고유하도록 도와주지만,
querySelectorAll
과 같은 셀렉터 메서드로서는 접근이 불가한다.
- 고유한 ID값을 생성함으로써 클라이언트와 서버 사이의
useDeferredValue
- 함수의 우선순위를 지정하는
useTransition
와 달리, 값의 업데이트 우선순위를 지정한다. (긴급한 작업이 끝나기 전까지 이전 상태값을 기억하면서 업데이트를 지연시킨다.) useMemo
,React.memo
와 같이 사용하여 자식 컴포넌트의 렌더를 지연시키는데 사용이 될 수 있다.
- 함수의 우선순위를 지정하는
useSyncExternalStore
- (공부 후 추가 예정입니다.)
useInsertionEffect
useLayoutEffect
처럼 DOM이 변경되기 전 동기적으로 실행되지만,useLayoutEffect
이 실행되기 전에 DOM에 스타일을 주입하기 위해 사용한다.css-in-js library
에 사용이 제한되므로 웬만하면useEffect
나useLayoutEffect
를 사용하는 것을 권장하고 있다.
Reference
'React' 카테고리의 다른 글
TIL | env파일 자동완성 및 Triple-Slash Directives 정리 (0) | 2022.08.18 |
---|---|
TIL | React + twin.macro(with styled-component) 세팅 (0) | 2022.06.10 |
TIL | useRef의 3가지 정의와 리턴값의 두가지 타입 (0) | 2022.01.12 |
TIL | 간단한 custom hook 만들어보기 2 (0) | 2021.12.20 |
TIL | 간단한 custom hook 만들어보기 1 (0) | 2021.12.15 |