react源码之render函数 一

import React, { Component } from "react";
import ReactDOM from "react-dom";

let jsx = (
  <div className="box border">
    <p className="p-bb border">这是一个jsx</p>
  </div>
);

ReactDOM.render(jsx, document.getElementById("root"));

如上是一个最基础的render过程,将创建好的jsx内容挂在到id为root的DOM上

在这个过程中执行了什么呢?代码中我们也没有看到对React的引用,但它却是必须的

大家都知道react框架有虚拟dom的定义,这里的步骤大概有

  • babel-loader对jsx进行编译
  • 通过React.createElement函数按照一定逻辑生成成携带标签及其字元素信息的vnode
  • 这个vnode则将作为render函数的真正入参,生成真实的node
  • 生成的node挂载到document.getElementById("root")指向的元素上

口说无凭,咱们看源码中的API 

version: react@16.11.0

createElement

返回一个更方便react框架(ReactElement)解析的对象

代码位置 packages\react\src\ReactElement.js

/**
 * type 组件类型(原生标签名称、函数组件、类组件)
 * 
 */
export function createElement(type, config, children) {
  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];
    }
    if (__DEV__) {
      if (Object.freeze) {
        Object.freeze(childArray);
      }
    }
    props.children = childArray;
  }

  // Resolve default props
  if (type && type.defaultProps) {
    const defaultProps = type.defaultProps;
    for (propName in defaultProps) {
      if (props[propName] === undefined) {
        props[propName] = defaultProps[propName];
      }
    }
  }
}


此处函数内部

  • 将config结构到函数的props中
  • 将arguments.length - 2 后的所有参数当作子组件放入props.children
  • 将type.defaultProps解构到props中

类似处理函数还有cloneElement

export function cloneElement(element, config, children) {
    if (element.type && element.type.defaultProps) {
      defaultProps = element.type.defaultProps;
    }
     return ReactElement(element.type, key, ref, self, source, owner, props);
}

  • 根据一个已有的element通过Object.assign({}, element.props)获取基础的pross
  • 通过结构config扩充props


render

render是reactDom的核心函数
代码位置:packages\react-dom\src\client\ReactDOMLegacy.js

export function render(
  element: React$Element<any>,
  container: Container,
  callback: ?Function,
) {
  return legacyRenderSubtreeIntoContainer(
    null,
    element,
    container,
    false,
    callback,
  );
}

根据上面的逻辑下节我们可以手动模拟实现jsx=>vnode=>node=>render的一个过程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值