Saber2pr's Blog

updateHostProperties

更新 DOM

dom 操作

函数声明

type Dict = { [k: string]: any };

function updateHostProperties(
  dom: (HTMLElement | Text) & Dict,
  oldProps: Dict,
  newProps: Dict
): void;

三个参数,dom 的类型为 HTMLElement 或者 Text,& Dict用于给这俩个类型添加属性索引,第二个参数为 dom 节点旧的属性,即 host Fiber 的 alternate.props,第三个参数为新的 host Fiber 的 props,由 React.createElement 生成的 VNode 节点提供。

函数实现

// props中需要过滤掉的属性
const fiberProps = ["children", "ref"];

function updateHostProperties(
  dom: (HTMLElement | Text) & Dict,
  oldProps: Dict,
  newProps: Dict
) {
  // 遍历newProps属性,diff
  Object.entries(newProps).forEach(([k, v]) => {
    // 过滤属性
    if (fiberProps.includes(k)) return;
    // style属性过滤掉,下文单独处理
    if (k === "style") return;
    // 新旧值没变化,跳过此次DOM操作
    if (oldProps[k] === v) return;
    // on开头的event事件handle变lower case
    if (k.startsWith("on")) k = k.toLowerCase();
    // 应用变化的属性到真实DOM
    dom[k] = v;
  });
  // style属性diff
  if ("style" in dom) {
    const newStyle = newProps.style || {};
    const oldStyle = oldProps.style || {};
    Object.entries(newStyle).forEach(([k, v]) => {
      // 新旧样式属性没变化,跳过此次DOM操作
      if (oldStyle[k] === v) return;
      // 应用变化的样式属性到真实DOM
      dom.style[k] = v;
    });
  }
}