preact 源码阅读-3
https://juejin.cn/post/6884862792923840526
将更新放到 enqueueRender
// component.js
BaseComponent.prototype.setState = function (update, callback) {
// only clone state when copying to nextState the first time.
let s;
if (this._nextState != null && this._nextState !== this.state) {
s = this._nextState;
} else {
s = this._nextState = assign({}, this.state);
}
if (typeof update == 'function') {
// Some libraries like `immer` mark the current state as readonly,
// preventing us from mutating it, so we need to clone it. See #2716
update = update(assign({}, s), this.props);
}
if (update) {
assign(s, update);
}
// Skip update if updater function returned null
if (update == null) return;
if (this._vnode) {
if (callback) {
this._stateCallbacks.push(callback);
}
enqueueRender(this);
}
};
setState调用,放到 enqueue中
defer调用,在nextTick 执行enqueue中的方法
renderComponent更新UI

// 先更新子组件
function process() {
let c;
rerenderQueue.sort(depthSort);
// Don't update `renderCount` yet. Keep its value non-zero to prevent unnecessary
// process() calls from getting scheduled while `queue` is still being consumed.
while ((c = rerenderQueue.shift())) {
if (c._dirty) {
let renderQueueLength = rerenderQueue.length;
renderComponent(c);
if (rerenderQueue.length > renderQueueLength) {
// When i.e. rerendering a provider additional new items can be injected, we want to
// keep the order from top to bottom with those new items so we can handle them in a
// single pass
rerenderQueue.sort(depthSort);
}
}
}
process._rerenderCount = 0;
}
renderComponent 方法,调用diff,更新页面