web前端开发

React源码解析之React.createElement()

2019-10-17  本文已影响0人  y先生_f18f

在第一次学习react的时候,我们总会带着许多疑问。比如我们看到下面的代码就会想:为什么我们只是引入了React,但是并没有明显的看到我们在其他地方用,这时我们就会想着既然没有用到,那如果删除之后会不会受到影响呢?答案当然是不行的。

import React from 'react';
import ReactDOM from 'react-dom';

let element = (
    <h1 id="title" className="bg" style={{color: 'red'}}>
        hello
        <span>world</span>
    </h1>
)

console.log({type: element.type, props:element.props})

ReactDOM.render(element,document.getElementById('root'));

当我们带着这个问题去研究的时候会发现其实在渲染element的时候调了React.createElement(),所以上面的问题就在这里找到了答案。

那么React.createElement()到底干了些什么事情呢?

  1. 我们看一看下面的代码
<h1 id="title" className="bg" style={{color: 'red'}}>
        hello
        <span>world</span>
</h1>

//上面的这段代码很简单,但是我们都知道react是所谓的虚拟dom,当然不可能就是我们看到的这样。当我们将上面的代码经过babel转译后,我们再看看

React.createElement("h1", {
  id: "title",
  className: "bg",
  style: {
    color: 'red'
  }
}, "hello", React.createElement("span", null, "world"));

  1. 那到底React.createElement干了些什么呢?
//方法接受三个参数,第一个参数是组件类型,第二个参数是要传递给组件的属性,第三个参数是children。方法最终会返回一个具有以下属性的对象

function createElement(type,config,children){
    let propName;
    const props = {};
    for(propName in config){
        props[propName] = config[propName]
    }
    const childrenLength = arguments.length - 2;   //减掉type config  看看后面还有几个儿子
    if(childrenLength === 1){
        props.children = children;
    }else if(childrenLength > 1){  //如果说儿子的数量大于1的话,props.children就是一个数组
        props.children = Array.from(arguments).slice(2)
    }
    return {type,props}
}

export default {
    createElement
}


/**
React.createElement("h1", {
  id: "title",
  className: "bg",
  style: {
    color: 'red'
  }
}, "hello", React.createElement("span", null, "world"));
 */

最后我们看到React通过createElement方法将组件或者元素转成ReactElement,并最终通过一系列操作渲染到页面成为HTMLElement。

上一篇下一篇

猜你喜欢

热点阅读