继续上一篇,还有4个API:
createElement,
cloneElement
createFactory
isValidElementreact
<div className="class" props="props" ref="ref" key="key"> <p>1</p> <p>2</p> </div>,
上面这段jsx代码经过babel转换后以下babel
React.createElement("div", { className: "class", props: "props", ref: "ref", key: "key" }, React.createElement("p", null, "1"), React.createElement("p", null, "2"));
// 不加入到props对象中的属性 const RESERVED_PROPS = { key: true, ref: true, __self: true, __source: true }; export function createElement(type, config, ...children) { let propName; const props = {}; let key = null; let ref = null; if (config !== null) { key = config.key || null; ref = config.ref || null; } if (config != null) { for (propName in config) { if ( hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName) ) { props[propName] = config[propName]; } } } // default props, 好比class App上挂了 App.defaultProps = {} 时的处理 if (type && type.defaultProps) { const defaultProps = type.defaultProps; for (propName in defaultProps) { if (!props[propName]) { props[propName] = defaultProps[propName]; } } } // react-dom 首次渲染 没有children参数 props.children = children.length === 0 ? null : children.length === 1 ? children[0] : children; return ReactElement(type, key, ref, props); }
const ReactElement = (type, key, ref, props) => { const element = { $$typeof: REACT_ELEMENT_TYPE, type, ref, key, props: props }; return element; };
export function cloneElement(element, config, ...children) { let propName; const props = Object.assign({}, element.props); let key = element.key; let ref = element.ref; if (config != null) { if (config.ref !== undefined) { ref = config.ref; } if (config.key !== undefined) { key = "" + config.key; } let defaultProps; if (element.type && element.type.defaultProps) { defaultProps = element.type.defaultProps; } for (propName in config) { if ( hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName) ) { if (config[propName] === undefined && defaultProps !== undefined) { // Resolve default props props[propName] = defaultProps[propName]; } else { props[propName] = config[propName]; } } } props.children = children.length === 0 ? null : children.length === 1 ? children[0] : children; return ReactElement(element.type, key, ref, props); } }
cloneElement的实现和createElement几乎同样,最后return的仍是一个ReactElement对象,只不过第一个参数不一样,第一个参数接收的是一个ReactElement,也就是createElement返回的那个对象dom
export function createFactory(type) { const factory = createElement.bind(null, type); factory.type = type; return factory; }
这个API好像已经没用了,也用不到函数
/** * 验证是不是react对象,主要是经过对象上的$$typeof属性 * @param {*} object */ export function isValidElement(object) { return ( typeof object === "object" && object !== null && object.$$typeof === REACT_ELEMENT_TYPE ); }
react这个包基本写完了code