export function diffProps()

in packages/react/src/utils.ts [20:122]


export function diffProps(
  oldProps: AnyProps,
  newProps: AnyProps,
): null | UpdatePayload {

  let updatePayload: null | any[] = null
  let propKey: string
  let styleName: string
  let styleUpdates: null | StyleProps = null

  // 寻找 oldProps 有但 newProps 中没有的,视为属性的删除
  for (propKey in oldProps) {
    if (
      newProps.hasOwnProperty(propKey)
      || !oldProps.hasOwnProperty(propKey)
      || oldProps[propKey] == null
    ) {
      continue
    }
    if (propKey === PropKey.Style) {
      // 如果 newProps 中没有 style 属性,视为删除了旧 style 中所有属性
      const oldStyle = oldProps[propKey]
      for (styleName in oldStyle) {
        if (oldStyle.hasOwnProperty(styleName)) {
          if (!styleUpdates) {
            styleUpdates = {}
          }
          styleUpdates[styleName] = undefined
        }
      }
    } else if (propKey === PropKey.Children) {
      // 跳过 children 的处理
    } else {
      (updatePayload = updatePayload || []).push(propKey, null)
    }
  }

  // 寻找 newProps 中有的属性,视为属性的新增或更新
  for (propKey in newProps) {
    const newProp = newProps[propKey]
    const oldProp = oldProps != null ? oldProps[propKey] : undefined
    if (
      !newProps.hasOwnProperty(propKey) ||
      newProp === oldProp ||
      (newProp == null && oldProp == null)
    ) {
      continue
    }
    // 特殊处理 style
    if (propKey === PropKey.Style) {
      if (oldProp) {
        // 删除先前样式中有但新样式中没有的
        for (styleName in oldProp) {
          if (
            oldProp.hasOwnProperty(styleName) &&
            (!newProp || !newProp.hasOwnProperty(styleName))
          ) {
            if (!styleUpdates) {
              styleUpdates = {}
            }
            // 通过设置样式值为 undefined 以删除该样式
            styleUpdates[styleName] = undefined
          }
        }
        // 更新与 lastProps 中不同的样式
        for (styleName in newProp) {
          if (
            newProp.hasOwnProperty(styleName) &&
            oldProp[styleName] !== newProp[styleName]
          ) {
            if (!styleUpdates) {
              styleUpdates = {}
            }
            styleUpdates[styleName] = newProp[styleName]
          }
        }
      } else {
        // 否则只需简单全部采用新属性即可
        if (!styleUpdates) {
          if (!updatePayload) {
            updatePayload = []
          }
          updatePayload.push(propKey, styleUpdates)
        }
        styleUpdates = newProp
      }
    } else if (propKey === PropKey.Children) {
      // string 和 number 类型的 children 通常是文本,我们在这里统一转换成 string
      if (typeof newProp === 'string' || typeof newProp === 'number') {
        (updatePayload = updatePayload || []).push(propKey, '' + newProp)
      }
    } else {
      // For any other property we always add it to the queue and then we
      // filter it out using the allowed property list during the commit.
      (updatePayload = updatePayload || []).push(propKey, newProp)
    }
  }
  if (styleUpdates) {
    (updatePayload = updatePayload || []).push(PropKey.Style, styleUpdates)
  }

  return updatePayload
}