# All files / react/helpers migrateProps.jsx

11.54% Statements 3/26
0% Branches 0/21
50% Functions 2/4
8% Lines 2/25

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
    80
    81
    82
    83
    84
    85
    86

    2x

    2x

     import React from 'react'

    const migrate = (oldProps, options) => {
      let newProps, msg
      for (let option of options) {
        if (option.src && option.dest) {
          // simple mode
          const src = option.src
          const dest = option.dest
          const oldProp = oldProps[src]
          if (oldProp === undefined) {
            continue
          }
          newProps = newProps || { ...oldProps } // copy props only if we change them
          newProps[dest] = oldProps[src]
          delete newProps[src]
          msg = `\`${src}\` is deprecated and has been migrated automatically, you should use \`${dest}\` now`
        } else if (option.fn) {
          // advanced mode
          const res = option.fn(newProps || oldProps)
          if (res.length !== 2) {
            throw new Error('migrateOption `fn` should return [newProps, msg].')
          }
          ;[newProps, msg] = res
        } else {
          console.warn(
            'migrateProps option is not valid, valid properties are `src`, `dest`, `fn`. You passed',
            option
          )
        }
        if (
          (process.env.NODE_ENV != 'production' ||
            window.SHOW_DEPRECATION_WARNINGS) &&
          msg
        ) {
          console.warn(`Deprecation: ${msg}`)
          msg = null
        }
      }
      // It is possible that no migration has been made, in this case newProps is undefined and we simply
      // return the oldProps
      return newProps || oldProps
    }

    /**
     * HOC to migrate old props for deprecation purpose.
     *
     * @example
     * Let's say we deprecated the property `withCross` of Modal and replaced
     * it with `closable`. To preserve backward compatibility we use the `migrate`
     * HOC, and provide an array of migrations to perform on the old props.
     *
     * ```
     * const migrateOptions = [{ src: 'withCross', dest: 'closable'}]
     * const Modal = migrate(migrateOptions)(_Modal)
     * ```
     *
     * Here we only have one migration, to rename `withCross` (source) to `closable` (destination).
     * For more complex migration, it is possible to use the `fn` property of a migration. In this
     * case you are responsible for providing a warning message as part of the return value of `fn`.
     *
     * ```
     * const migrateClosableAndReverse = oldProps => {
     *   let newProps
     *   if (oldProps.withoutCross) {
     *     newProps = {...oldProps}
     *     newProps.closable = !oldProps.withoutCross
     *     return [newProps, '`withoutCross` is deprecated. Use `closable` now. Be careful closable = !withoutCross']
     *   } else {
     *     return [oldProps, null]
     *   }
     *   return newProps || oldProps
     * }
     *
     * const migrateOptions = [{ fn: migrateClosableAndReverse }]
     * const Modal = migrate(migrateOptions)(_Modal)
     * ```
     *
     * @param  {Array} migrateOptions - Prop migrations that will be done on the old props
     * @return {[type]}         [description]
     */
    export default migrateOptions => Wrapped => oldProps => {
      const newProps = migrate(oldProps, migrateOptions, Wrapped)
      return <Wrapped {...newProps} />
    }