繼續上一篇,還有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