# All files / lib create-side-effect.js

100% Statements 40/40
100% Branches 8/8
100% Functions 3/3
100% Lines 40/40

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
    411x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    10x
    1x
    1x
    10x
    10x
    1x
    1x
    10x
    10x
    10x
    10x
    10x
    10x
    6x
    6x
    8x
    8x
    8x
    8x
    8x
    6x
    6x
    6x
    6x
    6x
    10x
     import { $$hooks } from './util/symbols';
    import { EMPTY, ActiveRenderState } from './util/types';

    /**
     * Allow a function component to hook into lifecycle methods in a manner
     * consistent with class components.
     *
     * @param {Function} sideEffectFn - A function that is called whenever the
     * component is mounted or updated. To invoke cleanup pass a second function
     * which will run whenever the component is removed.
     *
     * @returns {void}
     */
    export function createSideEffect(sideEffectFn) {
      if (ActiveRenderState.length === 0) {
        throw new Error('Cannot create side effect unless in render function');
      }

      if (typeof sideEffectFn !== 'function') {
        throw new Error('Missing function for side effect');
      }

      const [ activeComponent ] = ActiveRenderState;
      const activeHook = activeComponent[$$hooks].shift();

      // Only do this the first time.
      if (!activeHook) {
        // First schedule a componentDidMount
        activeComponent.componentDidMount = activeComponent.componentDidUpdate = () => {
          const unMount = sideEffectFn() || EMPTY.FUN;

          if (typeof unMount === 'function') {
            activeComponent.componentWillUnmount = () => unMount();
          }
        };

        // Return currentValue and setState.
        activeComponent[$$hooks].push(sideEffectFn);
      }
    }