【React源码】3.jsx&核心API

102 阅读1分钟

React.createElement的源码中做了如下几件事

  • 处理config,把除了保留属性外的其他config赋值给props
  • 把children处理后赋值给props.children
  • 处理defaultProps
  • 调用ReactElement返回一个jsx对象(virtual-dom)

推荐:babel编译jsx 站点查看jsx被编译后的结果

createElement函数

ReactElement函数

// ReactElement.js
export functin createElement(type, config, children) {
    let propName;
    const props = {}
    let key = null;
    let ref = null;
    let self = null;
    let source = null;
    
    if (config != null) {
        // 处理config,把除了保留属性外的其他config赋值给props
        // ...
    }
    
    const childrenLength = arguments.length - 2;
    // 把children处理后赋值给props.children
    // ...
    
    // 处理defaultProps
    // ...
    return ReactElement(
        type,
        key,
        ref,
        self,
        source,
        ReactCurrentOwner.current,
        props,
    )
}

const ReactElement = function(type, key, ref, self, source, owner, props) {
    const element = {
        $$typeof: REACT_ELEMENT_TYPE, // 表示是ReactElement类型
        type: type, // class 或function
        key: key,
        ref: ref,
        props: props, // props
        _owner: owner,
    }
    return element;
}

注:React.createElement方法,会把子节点,作为参数依次排开,比如:

function C() {
    return <div></div>
}

class B {
    render() {
        return <div></div>
    }
}

class A {
    render() {
        return <div name="a">aaa<B/></div>
    }
}

createElement.jpg

上面的 aaaB组件就是并排展开的

$$typeof

typeof表示的是组件的类型,例如在源码中有一个检测是否是合法的Element的函数,就是根据object.typeof表示的是`组件的类型`,例如在源码中有一个检测是否是合法的Element的函数,就是根据object.typeof === REACT_ELEMENT_TYPE来判断的、

//ReactElement.js
export function isValidElement(object) {
  return (
    typeof object === 'object' &&
    object !== null &&
    object.$$typeof === REACT_ELEMENT_TYPE
  );
}

type

  • 如果这个组件时ClassComponent,则type是class本身
  • 如果组件是FunctionComponent创建的,则type是这个function
  • 普通节点,字符串

源码中用ClassComponent.prototype.isReactComponent来区分二者

注意:class和function创建组件一定要首字母大写,不然会被当作普通节点,type就是字符串

jsx对象和fiber

jsx对象上没有优先级状态effectTag等标记,这些标记在Fiber对象上,在mount时Fiber根据jsx对象来构建,在update时根据最新状态的jsx和current Fiber对比,形成新的workInProgress Fiber,最后workInProgress Fiber切换成current Fiber。