当前位置: 代码迷 >> 综合 >> React.createElement 源码思考
  详细解决方案

React.createElement 源码思考

热度:20   发布时间:2024-02-02 10:52:44.0

https://github.com/facebook/react/blob/master/packages/react/src/ReactElement.js

// ** ReactElement 是 createElement的核心方法。作用是很简单,就是返回一个信息的承载容器,表明渲染节点的信息。
const ReactElement = function(type, key, ref, self, source, owner, props) {const element = {// $$typeof 用来标识我们的Element的什么类型的。比如我们在写jsx代码的时候,所有的节点都是通过createElement创建的,那么它的$$typeof就永远是REACT_ELEMENT_TYPE,也就是说大部分情况下 这个值都是固定的。(用于确定是否属于ReactElement)// 源码:const REACT_ELEMENT_TYPE = function() {}; // fake(虚假) Symbol$$typeof: REACT_ELEMENT_TYPE,type: type, // 记录节点类型,是原生组件还是class function Component or otherkey: key,ref: ref,props: props,// Record the component responsible for creating this element._owner: owner,};return element;
};// ** createElement 源码
// 主要是对 props属性 的扩展;最终返回 ReactElement 的结果。
export function createElement(type, config, children) {let propName;const props = {};// 下面这四个值,是根据 config的内容 进行获取的,若没有对应的值,则以null返回。let key = null;let ref = null;let self = null;let source = null;// 注意 这里对 ref, key 是单独处理,赋予一个全新的变量。if (config != null) {if (hasValidRef(config)) { // 判断 ref 是否有效ref = config.ref;}if (hasValidKey(config)) { // 判断 key 是否有效key = '' + config.key;}// config中其余的 属性 则添加到新props对象中for (propName in config) {props[propName] = config[propName] // config去除key/ref 其他属性的放到props对象中}}const childrenLength = arguments.length - 2;if (childrenLength === 1) {props.children = children;} else if (childrenLength > 1) {const childArray = Array(childrenLength); // 根据长度,创建含有对应个数的空数组。for (let i = 0; i < childrenLength; i++) {childArray[i] = arguments[i + 2];};{//冻结array 返回原来的childArray且不能被修改 防止有人修改库的核心对象 冻结对象大大提高性能if (Object.freeze) {Object.freeze(childArray);}}props.children = childArray; //父组件内部通过this.props.children获取子组件的值props.children = childArray;}if (type && type.defaultProps) {const defaultProps = type.defaultProps;for (propName in defaultProps) {if (props[propName] === undefined) {props[propName] = defaultProps[propName];}}}return ReactElement(type,key,ref,self,source,ReactCurrentOwner.current,props,);
}
  相关解决方案