第二章 实现Virtual DOM(React18源码解析二)

277 阅读1分钟

第一章 JSX(React18源码解析一)
第二章 实现Virtual DOM(React18源码解析二)
第三章 根节点关联根Fiber(React18源码解析三)
第四章 初始化UpdateQueue、添加update(React18源码解析四)
第五章 实现时间切片函数和拷贝Fiber(React18源码解析五)
第六章 构建FiberTree(React18源码解析六)
第七章 commit(React18源码解析七)
第八章 React中的事件(React18源码解析八)
第九章 useReducer、useState(React18源码解析九)
第十章 React的dom diff(React18源码解析十)
第十一章 React的Effect(React18源码解析十一)
第十二章 React的同步、并发渲染(React18源码解析十二)
第十三章 React高优打断低优、饥饿问题(React18源码解析十三)

一.JSX=>Virtual DOM

  • jsx
let element = (
  <h1>
    hello<span style={{ color: "red" }}>world</span>
  </h1>
);
console.log(element);
  • babel转换
const babel = require("@babel/core");
const sourceCode = `
<h1>
  hello<span style={{ color: "red" }}>world</span>
</h1>
`

const result = babel.transform(sourceCode, {
  plugins: [["@babel/plugin-transform-react-jsx", { runtime: "automatic" }]]
})

console.log(result.code);

/*打印*/
// _jsxs("h1", {
//   children: [
//     "hello",
//     _jsx("span", {
//       style: { color: "red" },
//       children: "world"
//     })
//   ]
// });
  • _jsxs输出 image.png

二.实现_jsxs

import hasOwnProperty from "shared/hasOwnProperty";
import { REACT_ELEMENT_TYPE } from "shared/ReactSymbols";

const RESERVED_PROPS = {
  key: true,
  ref: true,
  __self: true,
  __source: true,
};
function hasValidRef(config) {
  return config.ref !== undefined;
}

const ReactElement = (type, key, ref, props) => {
  const element = {
    $$typeof: REACT_ELEMENT_TYPE,
    type,
    key,
    ref,
    props,
  };
  return element;
};

export function jsxDEV(type, config, maybeKey) {
  let propName;
  const props = {};
  let key = null;
  let ref = null;

  if (maybeKey !== undefined) {
    key = "" + maybeKey;
  }

  if (hasValidRef(config)) {
    ref = config.ref;
  }

  for (propName in config) {
    if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
      props[propName] = config[propName];
    }
  }
  return ReactElement(type, key, ref, props);
}