# All files hooks.js

100% Statements 67/67
86.67% Branches 13/15
100% Functions 3/3
100% Lines 67/67

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
    681x
    1x
    1x
    3x
    3x
    3x
    3x
    3x
    3x
    3x
    3x
    3x
    3x
    3x
    3x
    3x
    3x
    1x
    6x
    6x
    6x
    6x
    6x
    6x
    6x
    1x
    1x
    14x
    14x
    14x
    14x
    14x
    14x
    14x
    14x
    14x
    14x
    14x
    14x
    6x
    6x
    6x
    1x
    1x
    14x
    14x
    14x
    3x
    1x
    1x
    14x
    14x
    14x
    14x
    14x
    4x
    3x
    3x
    3x
    1x
    1x
    1x
    1x
    14x
    14x
    14x
    14x
     import { useReducer, useEffect, useCallback, useMemo, useRef } from 'react'
    import { createMachine, transition, runEffects, cleanEffects } from './core.js'

    function initial({ context, machine }) {
      const initialState = { context }
      const initialEvent = { type: null }

      const [state, effects] = transition(machine, initialState, initialEvent)

      const curr = {
        machine,
        effects: effects || [],
        state,
      }

      return curr
    }

    function reduce(curr, action) {
      if (action.type === 'send') {
        const { event, machine } = action
        const [state, effects] = transition(machine, curr.state, event)
        return { ...curr, state, effects: effects || curr.effects }
      }
    }

    export function useMachine(create, context = {}, options = {}) {
      const { assign = 'assign', deps } = options

      const runningEffects = useRef()
      const firstRender = useRef(true)
      const machine = useMemo(() => createMachine(create), [create])
      const [curr, dispatch] = useReducer(reduce, { context, machine }, initial)
      const send = useCallback((event) => dispatch({ type: 'send', event, machine }), [
        machine,
        dispatch,
      ])

      useEffect(() => {
        runningEffects.current = cleanEffects(runningEffects.current)

        if (curr.effects.length) {
          runningEffects.current = runEffects(curr.effects, curr.state, send)
        }
      }, [send, curr.effects])

      useEffect(() => {
        return () => {
          runningEffects.current = cleanEffects(runningEffects.current)
        }
      }, [])

      const assignEffectDeps = [send].concat(deps || (context ? Object.values(context) : []))

      useEffect(() => {
        if (firstRender.current) {
          firstRender.current = false
          return
        }

        if (assign) {
          send({ type: assign, ...context })
        }
      }, assignEffectDeps)

      return [curr.state, send, curr.machine]
    }