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]); } }