anu - component

import { extend, isFn, options, clearArray, noop } from "./util";
import { CurrentOwner } from "./createElement";

/**
 *組件的基類
 *
 * @param {any} props
 * @param {any} context
 */
var mountOrder = 1;
export function Component(props, context) {
    //防止用戶在構造器生成JSX
    CurrentOwner.cur = this;
    this.__mountOrder = mountOrder++;
    this.context = context;
    this.props = props;
    this.refs = {};
    this.state = null;
    this.__pendingCallbacks = [];
    this.__pendingStates = [];
    this.__current = noop;
    /*
    * this.__hydrating = true 表示組件正在根據虛擬DOM合成真實DOM
    * this.__renderInNextCycle = true 表示組件須要在下一週期從新渲染
    * this.__forceUpdate = true 表示會無視shouldComponentUpdate的結果
    */
}

Component.prototype = {
    constructor: Component,//必須重寫constructor,防止別人在子類中使用Object.getPrototypeOf時找不到正確的基類
    replaceState() {
        console.warn("此方法末實現"); // eslint-disable-line
    },

    setState(state, cb) {
        debounceSetState(this, state, cb);
    },
    isMounted() {
        return !!this.__dom;
    },
    forceUpdate(cb) {
        debounceSetState(this, true, cb);
    },
    __mergeStates: function (props, context) {
        var n = this.__pendingStates.length;
        if (n === 0) {
            return this.state;
        }
        var states = clearArray(this.__pendingStates);
        var nextState = extend({}, this.state);
        for (var i = 0; i < n; i++) {
            var partial = states[i];
            extend(nextState, isFn(partial)
                ? partial.call(this, nextState, props, context)
                : partial);
        }
        return nextState;
    },

    render() { }
};

function debounceSetState(a, b, c) {
    if (a.__didUpdate) {//若是用戶在componentDidUpdate中使用setState,要防止其卡死
        setTimeout(function () {
            a.__didUpdate = false;
            setStateImpl.call(a, b, c);
        }, 300);
        return;
    }
    setStateImpl.call(a, b, c);
}
function setStateImpl(state, cb) {
    if (isFn(cb)) {
        this
            .__pendingCallbacks
            .push(cb);
    }
    let hasDOM = this.__dom;
    if (state === true) {//forceUpdate
        this.__forceUpdate = true;
    } else {//setState
        this
            .__pendingStates
            .push(state);
    }
    if (!hasDOM) { //組件掛載期
        //componentWillUpdate中的setState/forceUpdate應該被忽略 
        if (this.__hydrating) {
            //在掛載過程當中,子組件在componentWillReceiveProps裏調用父組件的setState,延遲到下一週期更新
            this.__renderInNextCycle = true;
        }

    } else { //組件更新期
        if (this.__receiving) {
            //componentWillReceiveProps中的setState/forceUpdate應該被忽略 
            return;
        }
        this.__renderInNextCycle = true;
        if (options.async) {
            //在事件句柄中執行setState會進行合併
            options.enqueueUpdate(this);
            return;
        }
        if (this.__hydrating) {
            // 在componentDidMount裏調用本身的setState,延遲到下一週期更新
            // 在更新過程當中, 子組件在componentWillReceiveProps裏調用父組件的setState,延遲到下一週期更新
            return;
        }
        //  不在生命週期鉤子內執行setState
        options.flushBatchedUpdates([this]);
    }
}
相關文章
相關標籤/搜索