본문 바로가기
📌 Front End/└ React

[React] 리액트 훅 - useDeferredValue, useTransition(상태값 지연, 상태변화 함수 지연)

by 쫄리_ 2024. 8. 30.
728x90
반응형

📌 useDeferredValue, useTransition 훅

이 두 훅은 React 애플리케이션을 더 부드럽고 빠르게 만들어 주는 도구입니다.

  • useDeferredValue 상태 값에 우선순위를 낮추는 Hook
  • useTransition 상태 변화를 일으키는 함수의 우선순위를 낮추는 Hook

📌 useDeferredValue

상태값 업데이트를 지연시켜 UI가 더 부드럽게 동작하도록 합니다.

상태가 바뀔 때, 그 변경 사항을 즉시 반영하지 않고 잠시 미뤄서 화면이 끊기지 않게 합니다.

사용자가 입력을 할 때, 그 입력으로 인해 화면이 바뀌는 것을

미뤄서 화면이 끊기지 않고 더 부드럽게 보이도록 합니다.

 

📝 useDeferredValue 형식

import { useDeferredValue } from 'react';

const deferredValue = useDeferredValue(value);

사용예시

  • 입력 필드
    • 사용자 입력 : "a" → 입력 필드에 "a"가 즉시 반영됩니다.
    • 사용자 입력 : "b" → 입력 필드에 "b"가 즉시 반영됩니다.
    • 사용자 입력 : "c" → 입력 필드에 "c"가 즉시 반영됩니다.
  • 지연된 검색어
    • 사용자가 "c"를 입력한 후, query는 즉시 "abc"로 변경됩니다.
    • 그러나 deferredQuery는 현재 "ab"일 수 있습니다. 
      이 값은 query가 바뀐 후에도 약간의 시간 차를 두고 "abc"로 업데이트됩니다.
  • 검색 결과
    • 입력 필드에는 "abc"가 즉시 보입니다.
    • 그러나 SearchResults 컴포넌트에는 deferredQuery가 반영됩니다. 
      만약 deferredQuery가 "ab"였다면, 화면에는 "Results for: ab"가 먼저 보입니다.
    • deferredQuery가 업데이트되어 "abc"로 바뀌면, 
      SearchResults 컴포넌트에 "Results for: abc"가 표시됩니다.
import { useState, useDeferredValue } from 'react';

function SearchPage() {
    const [query, setQuery] = useState('');		// 1. 사용자가 입력한 검색어
    const deferredQuery = useDeferredValue(query);	// 2. 지연된 검색어

    // ▶ 사용자가 입력하는 검색어와 관련된 검색 결과를 표시
    return (
        <div>
            <input 
                type="text" 
                value={query} 
                onChange={(e) => setQuery(e.target.value)} 
            />
            {/* 사용자가 입력한 검색어는 즉시 반영되지만, 검색 결과는 지연된 값을 사용 */}
            <SearchResults query={deferredQuery} /> {/* 3. 지연된 검색어로 결과 표시 */}
        </div>
    );
}

// ▶ SearchResults 컴포넌트는 지연된 검색어를 사용하여 검색 결과를 표시
function SearchResults({ query }) {
    return <div>Results for: {query}</div>;	// 지연된 검색어를 사용해 검색 결과 표시
}

 


📌 useTransition

긴 작업을 비동기적으로 처리하여 UI가 끊기지 않게 하는 것

시간이 오래 걸리는 작업을 백그라운드에서 처리하여,

사용자 인터페이스가 멈추거나 느려지지 않게 합니다.

긴 시간 동안 걸리는 작업(예: 데이터 로딩 등)을 비동기적으로 처리하여,

화면이 멈추거나 느려지지 않도록 합니다. 이로 인해 사용자에게 더 나은 경험을 제공합니다.

 

📝 useTransition 형식

  • isPending
    긴 작업이 진행 중인지 여부를 나타내는 상태입니다. 
    true이면 작업이 진행 중false이면 완료된 상태

  • startTransition
    긴 작업을 시작할 때 사용하는 함수입니다.
    startTransition(()=>{  })
import { useTransition } from 'react';

const [isPending, startTransition] = useTransition();

사용예시

  • 버튼 클릭 (사용자 동작)
    • 사용자가 "Load Data" 버튼을 클릭합니다.
    • 이 클릭 이벤트는 handleClick 함수를 실행합니다.
  • 비동기 작업 시작 (startTransition)
    • handleClick 함수 안에서 startTransition을 호출하여 긴 작업을 비동기적으로 처리합니다.
    • startTransition은 긴 작업이 끝나기 전에도 
      사용자 인터페이스가 부드럽게 반응할 수 있게 도와줍니다.
  • 긴 작업 처리 (loadDataFromServer)
    • loadDataFromServer 함수는 서버에서 데이터를 가져오는 시뮬레이션을 합니다.
    • 이 함수는 2초 후에 "Server Data"라는 문자열을 반환합니다.
  • 로딩 메시지 표시 (isPending)
    • isPending 상태가 true일 때, 
      로딩 중임을 나타내는 메시지인 "Loading..."이 화면에 표시됩니다.
    • 이 상태는 startTransition이 비동기 작업을 시작했을 때 자동으로 true로 설정됩니다.
  • 데이터 로딩 후 상태 업데이트
    • 2초가 지나고 loadDataFromServer 함수가 데이터를 반환하면, 
      setData가 호출되어 data 상태가 업데이트됩니다.
    • data가 업데이트되면 화면에 "Data: Server Data"가 표시됩니다.
  • 로딩 완료 후 데이터 표시
    • 비동기 작업이 끝나면 isPending 상태가 false로 변경됩니다.
    • 로딩 메시지가 사라지고, 새로운 데이터("Server Data")가 화면에 표시됩니다.
import { useTransition, useState } from 'react';

function TabContainer() {
    const [isPending, startTransition] = useTransition();	// 1. 비동기 상태와 시작 함수
    const [data, setData] = useState(null);			// 2. 로드된 데이터 상태

    function handleClick() {
        startTransition(() => {
            // 3. 긴 작업을 비동기적으로 처리
            loadDataFromServer().then(fetchedData => {
                setData(fetchedData); // 데이터가 로딩된 후 상태 업데이트
            });
        });
    }

    return (
        <div>
            <button onClick={handleClick}>Load Data</button>
            {isPending && <span>Loading...</span>}	{/* 4. 로딩 중 표시 */}
            {data && <div>Data: {data}</div>}		{/* 5. 로딩이 끝나면 데이터 표시 */}
        </div>
    );
}

function loadDataFromServer() {
    // 6. 데이터 로딩 시뮬레이션
    return new Promise(resolve => {
        setTimeout(() => resolve('Server Data'), 2000); // 2초 후에 데이터 반환
    });
}

 


 

728x90
반응형