이번 정비스프린트에 React 18로 버전업을 진행하였다.
React 18로 되면서 실제 업무에서 활용될 수 있는 훅스를 정리하고 공부하기 위해 글을 작성했다.
1. useDeferredValue
사용법
const deferredValue = useDeferredValue(value)
2. 실제 예시
export default function App() {
const [query, setQuery] = useState('');
const deferredQuery = useDeferredValue(query);
return (
<>
<label>
Search albums:
<input value={query} onChange={e => setQuery(e.target.value)} />
</label>
<Suspense fallback={<h2>Loading...</h2>}>
<SearchResults query={deferredQuery} />
</Suspense>
</>
);
}
query
는 기본 state이다.
deferredQuery
의 경우 해당 query state를useDefferedValue
훅을 사용한 반환값이다.
SearchResults
는 query props로 받은 값을 통해 데이터를 요청하고 해당 데이터를 보여주는 컴포넌트이다.
1. a를 입력했을 경우
(1)

a
를 입력하면 query
의 경우 바로 a
로 업데이트가 되고
deferredQuery
의 경우 아직 초깃값인 빈 “”
값을 갖게 된다.
(2)

Background에서 deferredQuery
의 값은 a
가 되고
SearchResults
를 a
의 값으로 렌더링을 한다.
(3)

Background에서 SearchResults
a
로 불러온 쿼리의 값의
데이터가 다 불러와져 렌더링이 마무리가 되었으면
실제 deferredQuery
는 a
, 데이터가 불러와진 SearchResults
로 렌더링을 진행한다.
2 a에서 → bc를 추가로 입력했을 경우
“a” 입력이 된 후에
연속해서 bc를 추가로 입력할 경우 어떻게 될까?
(1) b 추가 입력

먼저 query
의 경우 a
에서 ab
가 되고
deferredQuery
의 경우 이전의 a
값을 갖고 있게 된다.
이때 SearchResults 역시 기존 a의 쿼리를 통한 데이터를 보여주고 있다.
(2)

Background에서 deferredQuery
는 ab
이고
SearchResults
는 ab로
데이터를 요청하고 렌더링 시도를 한다.
(3) c
추가입력

c가 추가 입력되면서 리렌더링이 일어나며
query
는 abc
가 되고
이전에 발생했던 Background 렌더링을 버린다.
deferredQuery
는 아직 a
이다
(4)

다시 deferredQuery가 abc
인 상태에서 background 렌더링이 일어나며
SearchResults의 props가 abc인 컴포넌트 렌더링을 진행한다.
아직 실제 화면에선 SearchResults는 “a”의 결괏값을 보여주고 있다.
(5)

마지막으로 SearchResults 렌더링이 마무리가 되면
최종적으로 deferredQuery
의 경우 abc
SearchResults
는 abc
를 요청한 데이터의 결과를 보여주는 컴포넌트로 렌더링을 한다.
언제 유용할까?
Suspense
내부에서 loading 대신 이전 값(stale된 값) 유지되게 보이게 할 때위의 예시처럼
Suspense
를 활용할 때 loading 화면 대신 이전 데이터를 보이게 할 때 유용하다.
- 렌더링이 느린 컴포넌트 성능 최적화할 때
렌더링이 느린 컴포넌트에 내려주는 props를 deferredValue로 지연 업데이트를 시키게 되면
느린 컴포넌트의 렌더링을 background에서 업데이트 되기에 느린 컴포넌트 때문에 화면이 느려지는 것을
예방할 수 있다
단 이때 느린컴포넌트의 경우 memo로 감싸주어야 한다.
주의해야 할 것
useDeferredValue
를 통해 추가적인 네트워크 요청을 막을 수는 없다.실제 background에서 렌더링을 시도하는 것이기에 네트워크 요청은 한다.
TMI
- debounce,throttle 과는 차이가 있다.
debounce와 throttle은 시간이 정해져 있지만,
useDefferecValue를 활용하게 되면 기기별 렌더링 성능에 따라 시간이 다르다.
느낀 점
React18부터 concurrent mode가 도입되고 렌더링에 따른 스케줄링을 더 세밀하게 진행하게 되어
useDeferredValue훅스 개발이 가능해지지 않았나 싶다.
React 18버전 세부 구현 코드를 이해해야 해당 훅스 원리에 대해 더 깊게 이해할 수 있을 것 같다.
Reference
Uploaded by N2T