官方模拟版
2023年06月11日
一、react/jsx.js ReactElement
// const supportSymbol = typeof Symbol === 'function' && Symbol.for;
// export const REACT_ELEMENT_TYPE = supportSymbol
// ? Symbol.for('react.element')
// : 0xeac7;
import { REACT_ELEMENT_TYPE } from '../shared/ReactSymbols.js';
const ReactElement = function (type, key, ref, props) {
const element = {
$$typeof: REACT_ELEMENT_TYPE,
type,
key,
ref,
props
};
return element;
};
二、react/jsx.js jsx()
export function jsx(type, config, ...maybeChildren) {
let key = null;
const props = {};
let ref = null;
for (const prop in config) {
const val = config[prop];
if (prop === 'key') {
if (val !== undefined) {
key = '' + val;
}
continue;
}
if (prop === 'ref') {
if (val !== undefined) {
ref = val;
}
continue;
}
if ({}.hasOwnProperty.call(config, prop)) {
props[prop] = val;
}
}
const maybeChildrenLength = maybeChildren.length;
if (maybeChildrenLength) {
if (maybeChildrenLength === 1) {
props.children = maybeChildren[0];
} else {
props.children = maybeChildren;
}
}
return ReactElement(type, key, ref, props);
}
三、createElement()
四、react/index.js
import { jsx } from './jsx.js';
export default {
version: '0.0.0',
createElement: jsx
};
五、测试
import Babel from '@babel/core';
import React from '../react/index.js';
const templateElement = `<div className="home-page"> Home Page </div>`;
const templateClassComponent = `class ClassComponent { render() { return <div className="home-page"> Home Page </div> }}`;
const templateFunctionComponent = `function functionCompoent() { return <div className="home-page"> Home Page </div> }`;
const createElement = template => {
const result = Babel.transform(template, {
plugins: [['@babel/plugin-transform-react-jsx', { runtime: 'classic' }]]
});
const createElementStr = result.code;
const createElementFun = new Function('React', `return ${createElementStr}`);
const element = createElementFun(React);
return element;
};
const element = createElement(templateElement);
const classComponent = createElement(templateClassComponent);
const functionComponent = createElement(templateFunctionComponent);
console.log('element', JSON.stringify(element));