본문으로 건너뛰기

함수: useThrottler()

function useThrottler<TFn, TSelected>(
fn,
options,
selector): PreactThrottler<TFn, TSelected>;

정의 위치: preact-pacer/src/throttler/useThrottler.ts:168

제공된 함수의 실행 빈도를 제한하는 Throttler 인스턴스를 생성하는 하위 수준 Preact 훅입니다.

유연하고 상태 관리 방식에 구애받지 않도록 설계되었습니다. 스로틀러 인스턴스만 반환하므로 어떤 상태 관리 솔루션(useState, Redux, Zustand, Jotai 등)과도 통합할 수 있습니다. Preact의 useState와 직접 통합되는 더 간단한 상위 수준 훅은 useThrottledState를 참고합니다.

스로틀은 호출 횟수와 관계없이 지정된 시간 윈도우 안에서 함수가 최대 한 번만 실행되도록 합니다. 비용이 큰 작업이나 UI 업데이트의 요청률을 제한할 때 유용합니다.

상태 관리와 셀렉터

훅은 반응형 상태 관리에 TanStack Store를 사용합니다. 다음 두 가지 방식으로 상태 변경을 구독할 수 있습니다.

1. throttler.Subscribe HOC 사용(컴포넌트 트리 구독에 권장)

Subscribe HOC를 사용하면 컴포넌트 트리 깊은 곳의 상태 변경을 구독할 때 훅에 셀렉터를 전달할 필요가 없습니다. 자식 컴포넌트에서 상태를 구독하려는 경우에 적합합니다.

2. selector 매개변수 사용(훅 수준 구독)

selector 매개변수를 사용하면 어떤 상태 변경이 재렌더링을 트리거할지 지정할 수 있으며 관련 없는 상태가 변경될 때 불필요한 재렌더링을 방지하여 훅 수준의 성능을 최적화합니다.

기본적으로 반응형 상태 구독은 없습니다. 상태 추적을 명시적으로 활성화하려면 셀렉터 함수를 제공하거나 Subscribe HOC를 사용해야 합니다. 이렇게 하면 불필요한 재렌더링을 방지하고 컴포넌트가 업데이트되는 시점을 완전히 제어할 수 있습니다.

사용 가능한 상태 속성:

  • executionCount: 완료된 함수 실행 횟수
  • lastArgs: 가장 최근 maybeExecute 호출의 인수
  • lastExecutionTime: 마지막 함수 실행 시점의 타임스탬프(밀리초)
  • nextExecutionTime: 다음 실행이 가능한 시점의 타임스탬프(밀리초)
  • isPending: 스로틀러가 실행을 트리거할 타임아웃을 기다리는지 여부
  • status: 현재 실행 상태('disabled' | 'idle' | 'pending')

언마운트 동작

기본적으로 컴포넌트가 언마운트되면 훅은 대기 중인 실행을 취소합니다. 이를 사용자 지정하려면 onUnmount 옵션을 사용합니다. 예를 들어 대기 중인 작업을 대신 플러시하려면 다음과 같이 합니다.

const throttler = useThrottler(fn, {
wait: 1000,
onUnmount: (t) => t.flush()
});

타입 매개변수

TFn

TFn extends AnyFunction

TSelected

TSelected = { }

매개변수

fn

TFn

options

PreactThrottlerOptions&lt;TFn, TSelected>

selector

(state) => TSelected

반환값

PreactThrottler&lt;TFn, TSelected>

예시

// Default behavior - no reactive state subscriptions
const [value, setValue] = useState(0);
const throttler = useThrottler(setValue, { wait: 1000 });

// Subscribe to state changes deep in component tree using Subscribe HOC
<throttler.Subscribe selector={(state) => ({ isPending: state.isPending })}>
{({ isPending }) => (
<div>{isPending ? 'Processing...' : 'Ready'}</div>
)}
</throttler.Subscribe>

// Opt-in to re-render when execution count changes at hook level (optimized for tracking executions)
const [value, setValue] = useState(0);
const throttler = useThrottler(
setValue,
{ wait: 1000 },
(state) => ({ executionCount: state.executionCount })
);

// Opt-in to re-render when throttling state changes (optimized for loading indicators)
const [value, setValue] = useState(0);
const throttler = useThrottler(
setValue,
{ wait: 1000 },
(state) => ({
isPending: state.isPending,
status: state.status
})
);

// Opt-in to re-render when timing information changes (optimized for timing displays)
const [value, setValue] = useState(0);
const throttler = useThrottler(
setValue,
{ wait: 1000 },
(state) => ({
lastExecutionTime: state.lastExecutionTime,
nextExecutionTime: state.nextExecutionTime
})
);

// With any state manager
const throttler = useThrottler(
(value) => stateManager.setState(value),
{
wait: 2000,
leading: true, // Execute immediately on first call
trailing: false // Skip trailing edge updates
}
);

// Access the selected state (will be empty object {} unless selector provided)
const { executionCount, isPending } = throttler.state;