작년 7월에 리액트18의 신기술들을 둘러보면서 useDeferredValue를 debounce의 대안으로 사용할 수 있을까 라고 생각하고 글을 썼는데, 지금 보니 아닌 것 같아서 그때에 작성했던 글은 지우고 다시쓴다.
useDeferredValue는 값의 업데이트를 지연시키는 것으로, 서버와의 요청 수를 제한하기 위한 debounce와는 조금 다른 내용인 것 같다. (얼마든지 연계하여 이용할 수 있겠지만, 그건 개발자의 실력이고 개념자체는 조금 다른듯)
요약 : useDeferredValue는 최신값보다 늦게 업데이트 되는 지연된 값을 생성하는데 사용
우선 이 글 을 똑같이 따라해보았다.
const [text, setText] = useState("");
const deferredValue = useDeferredValue(text);
const boxes = useMemo(() => {
// deferredValue가 바뀔때마다 랜덤color박스들 20000개 생성하는 로직
// 가독성을 위해 코드 생략
}, [deferredValue]);
return (
...
<input value={value} onChange={(e) => setValue(e.target.value)} />
<div>{deferredValue}</div>
{boxes} // 랜덤color 박스 20000개
input아래 표시되는 deferredValue는 지연되어서 ui에 렌더링되고 있다.
useDeferredValue는 언제 사용할까
beta.reactjs.org 에서는 다음 3가지 상황에서 useDefferedValue를 추천한다.
- content가 로딩되는 동한 stale한 content를 보여주고 싶을때
- stale한 content를 다루고 싶을때
- 리렌더링을 지연시키고 싶을때
사용 예시
위의 세가지 경우를 다 포함하는 경우가 맨 위에서 링크로 소개한 글이어서 이 포스팅에서도 예시로 이용하기로 했다.
const [text, setText] = useState("");
const deferredValue = useDeferredValue(text);
첫 렌더링에서 deferred value는 text와 같다.(deferred value = '')
업데이트 되는 동안, deferred value는 text보다 뒤쳐져서 업데이트 된다. 그리고 리액트는 deferred value가 업데이트 되는것을 기다리지 않고 UI를 렌더링한다.
const [text, setText] = useState("");
const deferredValue = useDeferredValue(text);
const boxes = useMemo(() => {
// deferredValue가 바뀔때마다 랜덤color박스들 20000개 생성하는 로직
// 가독성을 위해 코드 생략
}, [deferredValue]);
deferredValue가 변경될때마다 boxes(20000개의 박스들)은 새롭게 리렌더링되는데, deferredValue가 지연되어 업데이트 되기 때문에 boxes들의 리렌더링도 지연되는 것이다.
때문에 gif와 같이 타이핑을 쉴새없이 몰아치는 동안에는 deferredValue와 boxes들이 업데이트되지 않는다.
그럼 만약 deferredValue를 이용하지 않는다면 어떻게 될까??
맨 위 코드의 deferredValue 자리에 text를 넣어주었다.
const [text, setText] = useState("");
const boxes = useMemo(() => {
// text가 바뀔때마다 랜덤color박스들 20000개 생성하는 로직
// 가독성을 위해 코드 생략
}, [text]);
return (
...
<input value={value} onChange={(e) => setValue(e.target.value)} />
<div>{text}</div>
{boxes} // 랜덤color 박스 20000개
타자치는 소리가 들리지 않아서 모르겠지만, 타자를 막 치고 있는 중에도 화면의 변화가 없다.
boxes 리렌더링 의존성이 deferredValue에 걸려있을때는 boxes들의 리렌더링이 지연되어서 렉이 걸리지 않았는데,
boxes 리렌더링 의존성을 value로 변경하니 2000개의 boxes를 리렌더링 시키는 작업이 계속 추가되면서 결국에는 렉이 걸리게 된다.
결론
서버에서 응답 data 폭주하듯 쏟아지고, 이를 매번 UI에 표현하는것이 부담이 된다면 응답 data에 deferredValue를 걸어보면 좋을 것 같다.
'개발 > React' 카테고리의 다른 글
리액트에서 스크롤,드래그 둘 다 되는 슬라이더 (0) | 2023.04.26 |
---|---|
react18 : flushSync (0) | 2023.04.10 |
부분렌더링 Input 컴포넌트 (0) | 2023.03.01 |
useState 동기화 하는 2가지 방법 (0) | 2023.02.28 |
react 18로 업글시 children 타입에러 : Type '{ children: Element; }' has no properties in common with type 'IntrinsicAttributes'. (0) | 2023.01.30 |