useDeferredValue는 React 18에서 훅이다.
useDefferdValue는 복잡하거나 무거운 렌더링 작업에서 유용하게 사용할 수 있다.
useDeferredValue는 값을 지연시켜, 작업동안의 UI의 응답성을 유지할 수 있도록 돕는다.
useDeferredValue의 개념
useDeferredValue는 값이 즉시 업데이트되지 않아도 될 때 사용된다.
예를 들어, 사용자가 텍스트를 입력할 때, 입력된 텍스트를 기반으로 검색 결과를 보여주는 컴포넌트가 있다고 가정했을때, 사용자가 빠르게 타이핑할 때마다 검색 결과를 업데이트하는 것은 불필요한 작업이 된다. 이러한 경우에 useDeferredValue를 사용하여 텍스트 입력에 딜레이를 주어 불필요한 렌더링을 방지한다.
코드로 알아보기
ResultList.tsx
type ResultsListProps = {
results: string[],
};
const ResultsList: React.FC<ResultsListProps> = ({ results }) => {
if (results.length === 0) {
return <p>No results found.</p>;
}
return (
<ul>
{results.map((result, index) => (
<li key={index}>{result}</li>
))}
</ul>
);
};
export default ResultsList;
performHeavyComputation 함수 ( 함수 구분하기 위해 아래의 코드와 별도로 분리 시킴)
const performHeavyComputation = (query: string) => {
// 가정: 아주 큰 데이터셋이 있다고 가정
let result = '';
for (let i = 0; i < 1000000; i++) {
result = query.split('').reverse().join(''); // 단순한 무거운 작업
}
const largeDataset = [
'Apple',
'Banana',
'Cherry',
'Date',
'Elderberry',
'Fig',
'Grape',
'Honeydew',
'Kiwi',
'Lemon',
'Mango',
'Nectarine',
'Orange',
'Papaya',
'Quince',
'Raspberry',
'Strawberry',
'Tangerine',
'Ugli Fruit',
'Vanilla',
'Watermelon',
'Xigua',
'Yellow Passion Fruit',
'Zucchini',
];
return largeDataset.filter((item) => item.toLowerCase().includes(query.toLowerCase()));
};
page.tsx
'use client';
import { useDeferredValue, useEffect, useState } from 'react';
import ResultsList from './ResultsList';
const UseDefferdValue = () => {
const [input, setInput] = useState('');
const deferredInput = useDeferredValue(input);
const [inputRenderCount, setInputRenderCount] = useState(0);
const [deferredRenderCount, setDeferredRenderCount] = useState(0);
useEffect(() => {
setInputRenderCount((prev) => prev + 1);
}, [input]);
useEffect(() => {
setDeferredRenderCount((prev) => prev + 1);
}, [deferredInput]);
const results = performHeavyComputation(deferredInput);
return (
<div>
<input type="text" value={input} onChange={(e) => setInput(e.target.value)} placeholder="검색어를 입력하세요" />
<ResultsList results={results} />
<div>
<p>Input Value: {input}</p>
<p>Deferred Input Value: {deferredInput}</p>
<p>Input Render Count: {inputRenderCount}</p>
<p>Deferred Render Count: {deferredRenderCount}</p>
</div>
</div>
);
};
export default UseDefferdValue;
사용자가 텍스트를 입력할 때 input 값은 즉시 업데이트되지만, deferredInput 값은 렌더링이 필요한 시점에서만 업데이트 된다. 이럴 경우. 결과를 보여주는 ResultsList 컴포넌트가 불필요하게 자주 렌더링되지 않도록 방지할 수 있다.
useDeferredValue를 사용하는 이유
useDefferdValue는 UI 업데이트가 사용자 인터랙션을 따라가지 못할 때, 즉시 렌더링하지 않고 딜레이를 주어 더 부드러운 사용자 경험을 제공하는 것이 큰 목표다. 또한 무겁거나 복잡한 작업에서 사용자 불편함을 느끼지 않고 사용할 수 있게 한다.
useDeferredValue의 주의사항
useDeferredValue는 단순히 값을 지연시키는 것이므로, 모든 상황에 적합하지 않다. 또한 복잡한 상태 관리가 필요하거나 여러 상태 간의 의존성이 있는 경우, useDeferredValue를 사용하는 것 보다 다른 방법을 사용해보자.
useDeferredValue와 useTransition의 차이점
useTransition은 비동기적으로 상태 전환을 관리하는 데 사용되고, useDeferredValue는 값 자체를 지연시키는 데 사용된다는 차이점이 있다.useTransition은 입력이 바뀌었을 때 전체 상태 업데이트를 지연시키고, isPending 상태를 통해 로딩 스피너와 같은 UI 피드백을 제공할 수 있습니다. 반면, useDeferredValue는 값의 변화를 지연시킬 뿐, 추가적인 UI 상태 관리는 하지 않는다.
'Stack > React' 카테고리의 다른 글
| useTransition 알아보기 (0) | 2024.08.16 |
|---|---|
| useId 알아보기 (0) | 2024.08.16 |
| useReducer 알아보기 (0) | 2024.08.12 |
| useLayoutEffect 에 대해 알아보기 (2) | 2024.08.12 |
| useCallback 이란? (0) | 2024.08.07 |