跳到主要内容

官方模拟版

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));