@modern-kit/react
Version:
1 lines • 4.06 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","sources":["../../../src/hooks/useBlockMultipleAsyncCalls/index.ts"],"sourcesContent":["import { useCallback, useRef, useState } from 'react';\n\ninterface UseBlockMultipleAsyncCallsReturnType {\n isError: boolean;\n isLoading: boolean;\n blockMultipleAsyncCalls: <T>(\n callback: () => Promise<T>\n ) => Promise<T | undefined>;\n}\n\n/**\n * @description `useBlockMultipleAsyncCalls` 훅은 진행 중인 비동기 호출이 있을 때 중복 호출을 방지하기 위한 커스텀 훅입니다.\n *\n * `debounce`는 함수의 중복 호출을 방지하는 데 대부분의 경우에 효과적입니다.\n * 하지만, debounce는 비동기 작업의 완료를 보장하지 않기 때문에 다음과 같은 한계가 있습니다:\n *\n * 1. `debounce` 시간이 API 응답 시간보다 짧을 경우: 비동기 작업이 완료되지 않은 상태에서 `다시 호출`될 수 있습니다.\n * 2. `debounce` 시간이 API 응답 시간보다 길 경우: 비동기 작업이 완료되었지만 `버튼`과 같은 요소가 여전히 `비활성화`되어 있을 수 있습니다.\n * 3. `즉각적인 반응`을 원하는 경우: `debounce`는 호출을 지연시키기 때문에 사용자에게 `즉각적인 반응`을 보여주기에 제한적입니다.\n *\n * 대부분의 경우에 `debounce`만으로 충분하지만, 위와 같은 한계점을 대응하고자 한다면 `useBlockMultipleAsyncCalls`를 사용할 수 있습니다.\n *\n * @returns {UseBlockMultipleAsyncCallsReturnType} 다음을 포함하는 객체:\n * - `isError`: 비동기 작업 중 에러가 발생했는지 나타내는 불리언 값\n * - `isLoading`: 현재 비동기 작업이 진행 중인지 나타내는 불리언 값\n * - `blockMultipleAsyncCalls`: 비동기 작업을 래핑하여 중복 호출을 방지하는 함수\n *\n * @example\n * ```tsx\n * const Example = () => {\n * const { isError, isLoading, blockMultipleAsyncCalls } = useBlockMultipleAsyncCalls();\n *\n * const fetchApi = async () => {\n * const data = await fetchData();\n * // 데이터 처리\n * };\n *\n * const handleClick = () => {\n * blockMultipleAsyncCalls(fetchApi);\n * };\n *\n * return (\n * <div>\n * <button onClick={handleClick} disabled={isLoading}>데이터 불러오기</button>\n * {isError && <p>에러 발생</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useBlockMultipleAsyncCalls(): UseBlockMultipleAsyncCallsReturnType {\n const [isLoading, setIsLoading] = useState(false);\n const [isError, setIsError] = useState(false);\n const isCalled = useRef(false);\n\n const blockMultipleAsyncCalls = useCallback(\n async <T>(callback: () => Promise<T>) => {\n if (isCalled.current) {\n return;\n }\n\n isCalled.current = true;\n setIsLoading(true);\n setIsError(false);\n\n try {\n const result = await callback();\n return result;\n } catch (error) {\n setIsError(true);\n throw error;\n } finally {\n isCalled.current = false;\n setIsLoading(false);\n }\n },\n []\n );\n\n return {\n isError,\n isLoading,\n blockMultipleAsyncCalls,\n };\n}\n"],"names":["useState","useRef","useCallback"],"mappings":";;;;AAkDO,SAAS,0BAAA,GAAmE;AACjF,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIA,eAAS,KAAK,CAAA;AAChD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,eAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,QAAA,GAAWC,aAAO,KAAK,CAAA;AAE7B,EAAA,MAAM,uBAAA,GAA0BC,iBAAA;AAAA,IAC9B,OAAU,QAAA,KAA+B;AACvC,MAAA,IAAI,SAAS,OAAA,EAAS;AACpB,QAAA;AAAA,MACF;AAEA,MAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AACnB,MAAA,YAAA,CAAa,IAAI,CAAA;AACjB,MAAA,UAAA,CAAW,KAAK,CAAA;AAEhB,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,GAAS,MAAM,QAAA,EAAS;AAC9B,QAAA,OAAO,MAAA;AAAA,MACT,SAAS,KAAA,EAAO;AACd,QAAA,UAAA,CAAW,IAAI,CAAA;AACf,QAAA,MAAM,KAAA;AAAA,MACR,CAAA,SAAE;AACA,QAAA,QAAA,CAAS,OAAA,GAAU,KAAA;AACnB,QAAA,YAAA,CAAa,KAAK,CAAA;AAAA,MACpB;AAAA,IACF,CAAA;AAAA,IACA;AAAC,GACH;AAEA,EAAA,OAAO;AAAA,IACL,OAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}