# All files / src/_hooks DelayedCallback.tsx

96.42% Statements 27/28
78.57% Branches 11/14
80% Functions 8/10
95.83% Lines 23/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    8061x
    61x

    61x
    94x

    61x
    88x
    2x

    86x
    75x

    11x

    61x
    2813x
    2813x
    2813x
    2813x

    2813x

    2813x

    2813x
    651x

    382x

    2813x

    82x

    82x

     import React from 'react'
    import { TimerApi, useTimer } from './Timer'

    /* TYPES */

    export type BeforeResult = Promise<any> | boolean | undefined | void

    export type BeforeCallback = (event: Event) => BeforeResult

    interface DelayedCallbackConfig {
      after?: (event: Event) => void
      before?: BeforeCallback
      delay: number
      timer?: TimerApi
    }

    function noop() {}

    function returnTrue() {
      return true
    }

    /**
     * @deprecatedSince 9
     * @deprecated Never officially documented/supported
     */
    export function isPromise(obj: any): obj is Promise<any> {
      return typeof obj === 'object' && typeof obj.then === 'function'
    }

    /**
     * @deprecatedSince 9
     * @deprecated Never officially documented/supported
     */
    export function wrapPromise(result: BeforeResult): Promise<any> {
      if (isPromise(result)) {
        return result
      }

      if (typeof result === 'boolean') {
        return Promise.resolve(result)
      }

      return Promise.resolve(true)
    }

    /* HOOK */

    /**
     * @deprecatedSince 9
     * @deprecated Never officially documented/supported
     */
    export function useDelayedCallback({
      after = noop,
      before = returnTrue,
      delay = 0,
      timer,
    }: DelayedCallbackConfig) {
      const defaultTimer = useTimer({})

      const t = timer || defaultTimer

      React.useEffect(() => {
        return () => {
          // cancel timeout on unmount
          t.cancel()
        }
      }, [])

      return React.useCallback(
        (event: any) => {
          return wrapPromise(before(event)).then(
            (shouldUpdate: boolean) =>
              shouldUpdate && t.setTimer(() => after(event), delay)
          )
        },
        [delay, before, after, t]
      )
    }