function renderComponent(instance, opts, mountAll, isChild) {
	if (instance._disable) return;
   
	let props = instance.props,
		state = instance.state,
		context = instance.context,
		previousProps = instance.prevProps || props,
		previousState = instance.prevState || state,
		previousContext = instance.prevContext || context,
        vnode = instance._currentElement,
        isUpdate = vnode._hostNode
		skip = false,
		rendered, inst, cbase;

	// if updating
	if (isUpdate) {
		instance.props = previousProps;
		instance.state = previousState;
		instance.context = previousContext;
		if (instance.__forceUpdate
            && instance.shouldComponentUpdate
            //nextProps, nextState, nextContext
			&& instance.shouldComponentUpdate(props, state, context) === false) {
			skip = true;
		}
		else if (instance.componentWillUpdate) {
            //nextProps, nextState, nextContext
			instance.componentWillUpdate(props, state, context);
		}
		instance.props = props;
		component.state = state;
		instance.context = context;
	}

	instance.prevProps = instance.prevState = instance.prevContext = instance.nextBase = null;
	instance._dirty = false;

	if (!skip) {
        rendered = instance.render();
        rendered = checkNull(rendered)

		// context to pass to the child, can be updated via (grand-)parent instance
		if (instance.getChildContext) {
			context = Object.apply({}, context, instance.getChildContext());
		}

		let childComponent = rendered && rendered.type,
			toUnmount, base;

		if (typeof childComponent==='function') {
			// set up high order component link

			let childProps = getNodeProps(rendered);
			inst = initialChildComponent; //子组件的实例

			if (inst && inst.constructor===childComponent && childProps.key==inst.__key) {
				setComponentProps(inst, childProps, SYNC_RENDER, context, false);
			}	else {
				toUnmount = inst;

				instance._childInstance = inst = createComponent(childComponent, childProps, context);
				inst.nextBase = inst.nextBase || nextBase;
				inst._parentInstance = instance;
				setComponentProps(inst, childProps, NO_RENDER, context, false);
				renderComponent(inst, SYNC_RENDER, mountAll, true);
			}

			base = inst.base;
		}
		else {
			cbase = initialBase;

			// destroy high order component link
			toUnmount = initialChildComponent;
			if (toUnmount) {
				cbase = component._component = null;
			}

			if (initialBase || opts===SYNC_RENDER) {
				if (cbase) cbase._component = null;
				base = diff(cbase, rendered, context, mountAll || !isUpdate, initialBase && initialBase.parentNode, true);
			}
		}

		if (initialBase && base!==initialBase && inst!==initialChildComponent) {
			let baseParent = initialBase.parentNode;
			if (baseParent && base!==baseParent) {
				baseParent.replaceChild(base, initialBase);

				if (!toUnmount) {
					initialBase._component = null;
					recollectNodeTree(initialBase, false);
				}
			}
		}

		if (toUnmount) {
			unmountComponent(toUnmount);
		}

		component.base = base;
		if (base && !isChild) {
			let componentRef = component,
				t = component;
			while ((t=t._parentComponent)) {
				(componentRef = t).base = base;
			}
			base._component = componentRef;
			base._componentConstructor = componentRef.constructor;
		}
	}

	if (!isUpdate || mountAll) {
		mounts.unshift(component);
	}
	else if (!skip) {
		// Ensure that pending componentDidMount() hooks of child components
		// are called before the componentDidUpdate() hook in the parent.
		// Note: disabled as it causes duplicate hooks, see https://github.com/developit/preact/issues/750
		// flushMounts();

		if (component.componentDidUpdate) {
			component.componentDidUpdate(previousProps, previousState, previousContext);
		}
		if (options.afterUpdate) options.afterUpdate(component);
	}

	if (component._renderCallbacks!=null) {
		while (component._renderCallbacks.length) component._renderCallbacks.pop().call(component);
	}

	if (!diffLevel && !isChild) flushMounts();
}

