Skip to main content

useBlockMultipleAsyncCalls

useBlockMultipleAsyncCalls 훅은 진행 중인 비동기 호출이 있을 때 중복 호출을 방지하기 위한 커스텀 훅입니다.

debounce는 함수의 중복 호출을 방지하는 데 대부분의 경우에 효과적입니다. 하지만, debounce는 비동기 작업의 완료를 보장하지 않기 때문에 다음과 같은 한계가 있습니다:

  1. debounce 시간이 API 응답 시간보다 짧을 경우: 비동기 작업이 완료되지 않은 상태에서 다시 호출될 수 있습니다.
  2. debounce 시간이 API 응답 시간보다 길 경우: 비동기 작업이 완료되었지만 버튼과 같은 요소가 여전히 비활성화되어 있을 수 있습니다.
  3. 즉각적인 반응을 원하는 경우: debounce는 호출을 지연시키기 때문에 사용자에게 즉각적인 반응을 보여주기에 제한적입니다.

대부분의 경우에 debounce만으로 충분하지만, 위와 같은 한계점을 대응하고자 한다면 useBlockMultipleAsyncCalls를 사용할 수 있습니다.


Code

🔗 실제 구현 코드 확인

Interface

typescript
interface UseBlockMultipleAsyncCallsReturnType {
isError: boolean;
isLoading: boolean;
blockMultipleAsyncCalls: <T>(
callback: () => Promise<T>
) => Promise<T | undefined>;
}
typescript
function useBlockMultipleAsyncCalls(): UseBlockMultipleAsyncCallsReturnType

Usage

typescript
import React, { useState } from 'react';
import { useBlockMultipleAsyncCalls } from '@modern-kit/react';

interface Value {
userId: number;
id: number;
title: string;
completed: boolean;
}

const Example = () => {
const [blockingCount, setBlockingCount] = useState(1);
const [nonBlockingCount, setNonBlockingCount] = useState(1);
const [value, setValue] = useState<Value | null>(null);

const { isError, isLoading, blockMultipleAsyncCalls } = useBlockMultipleAsyncCalls();

const fetchApi = async () => {
const res = await fetch(
`https://jsonplaceholder.typicode.com/todos/${blockingCount}`
).then((response) => response.json());

setValue(res);
setBlockingCount(blockingCount + 1);
};

const handleClick = () => {
setNonBlockingCount(nonBlockingCount + 1);
blockMultipleAsyncCalls(fetchApi); // (*) Promise 반환하는 함수를 인자로 넣어주세요.
};

return (
<div>
<button onClick={handleClick}>버튼 클릭</button>
<div>
<p>BlockingCount: {blockingCount}</p>
<p>NonBlockingCount: {nonBlockingCount}</p>
</div>
{isLoading ? <p>로딩중</p> : <p>{value?.title}</p>}
{isError && <p>에러 발생</p>}
</div>
);
};

Example

BlockingCount: 1

NonBlockingCount: 1