React源码之 从开始说起

其实react和vue思想差不多,render生成虚拟节点,对比改变真实节点响应。

 

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>Hello React!</title>
    <!--<script src="./react.development.js"></script>-->
    <!--<script src="./react-dom.development.js"></script>-->
    <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
    <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>

<div id="example"></div>
<script type="text/babel">
    class Clock extends React.Component {
        render() {
            return (
                <div><h1></h1>
                </div>
            );
        }
    }
    ReactDOM.render(
        <Clock></Clock>,
        document.getElementById('example')
    );
</script>

</body>
</html>

 

比如上面的代码,ReactDOM来自react-dom.development.js的11746行,render方法在17771行,

render: function (element, container, callback) {
            return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
        },

  参数里的container就是example这个div Node,element的话比较复杂:在js里写<Clock>这样的语法并不报错是因为<script type="text/babel">这里,jsx语法经过babel转义了,转义后的代码是:

'use strict';

var _createClass = function() {
    function defineProperties(target, props) {
        for (var i = 0; i < props.length; i++) {
            var descriptor = props[i];
            descriptor.enumerable = descriptor.enumerable || false;
            descriptor.configurable = true;
            if ("value"in descriptor)
                descriptor.writable = true;
            Object.defineProperty(target, descriptor.key, descriptor);
        }
    }
    return function(Constructor, protoProps, staticProps) {
        if (protoProps)
            defineProperties(Constructor.prototype, protoProps);
        if (staticProps)
            defineProperties(Constructor, staticProps);
        return Constructor;
    }
    ;
}();

function _classCallCheck(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
        throw new TypeError("Cannot call a class as a function");
    }
}

function _possibleConstructorReturn(self, call) {
    if (!self) {
        throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
    }
    return call && (typeof call === "object" || typeof call === "function") ? call : self;
}

function _inherits(subClass, superClass) {
    if (typeof superClass !== "function" && superClass !== null) {
        throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
    }
    subClass.prototype = Object.create(superClass && superClass.prototype, {
        constructor: {
            value: subClass,
            enumerable: false,
            writable: true,
            configurable: true
        }
    });
    if (superClass)
        Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}

var Clock = function(_React$Component) {
    _inherits(Clock, _React$Component);

    function Clock() {
        _classCallCheck(this, Clock);

        return _possibleConstructorReturn(this, (Clock.__proto__ || Object.getPrototypeOf(Clock)).apply(this, arguments));
    }

    _createClass(Clock, [{
        key: 'render',
        value: function render() {
            return React.createElement('div', null, '123');
        }
    }]);

    return Clock;
}(React.Component);

ReactDOM.render(React.createElement(Clock, null), document.getElementById('example'));

上面逻辑不复杂,就是一些继承验证的东西,可以看出element参数其实是React.createElement(Clock, null)。

在ReactDOM.render的时候,Clock这个function对象,1、有了父类React.Component,在被调用的时候,如果自己定义了构造器,那么使用自己的,没有的话使用父类的构造器。2、原型上有自己定义的方法。

而3、createElement的第二个参数这里虽然是null,但是如果传递的属性的话,是一个对象。到此为止,创建一个虚拟节点(普通节点+组件两种,这里主要讨论组件)的所有要素:一个构造方法(以便生成一个对象来保存组件的内部变量)+所有的组件对象都继承同一个父类(Vue里是所有的组件都是VueComponent的实例,继承的是Vue这个父类,这里父类是React.Component,子类自己写)+传递给组件的属性

 

转载于:https://www.cnblogs.com/chuliang/p/10801045.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值