Skip to content

Commit e932cfc

Browse files
authoredJan 10, 2025··
Backport state settling (#641)
1 parent d4ff246 commit e932cfc

File tree

3 files changed

+28
-7
lines changed

3 files changed

+28
-7
lines changed
 

‎.changeset/silver-crabs-sniff.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@preact/signals": patch
3+
---
4+
5+
Change the way we deal with state settling hooks, when we know we are dealing with hooks that can settle their A -> B -> A state (and wind up at the same value). We should not verbatim rerender in our custom shouldComponentUpdate. Instead we should trust that hooks have handled their own state settling.

‎packages/preact/src/index.ts

+18-7
Original file line numberDiff line numberDiff line change
@@ -328,16 +328,27 @@ Component.prototype.shouldComponentUpdate = function (
328328
// });
329329
// }
330330

331-
// if this component used no signals or computeds, update:
332-
if (!hasSignals && !(this._updateFlags & HAS_COMPUTEDS)) return true;
333-
334-
// if there is a pending re-render triggered from Signals,
335-
// or if there is hook or class state, update:
336-
if (this._updateFlags & (HAS_PENDING_UPDATE | HAS_HOOK_STATE)) return true;
337-
338331
// @ts-ignore
339332
for (let i in state) return true;
340333

334+
if (this.__f || (typeof this.u == "boolean" && this.u === true)) {
335+
const hasHooksState = this._updateFlags & HAS_HOOK_STATE;
336+
// if this component used no signals or computeds and no hooks state, update:
337+
if (!hasSignals && !hasHooksState && !(this._updateFlags & HAS_COMPUTEDS))
338+
return true;
339+
340+
// if there is a pending re-render triggered from Signals,
341+
// or if there is hooks state, update:
342+
if (this._updateFlags & HAS_PENDING_UPDATE) return true;
343+
} else {
344+
// if this component used no signals or computeds, update:
345+
if (!hasSignals && !(this._updateFlags & HAS_COMPUTEDS)) return true;
346+
347+
// if there is a pending re-render triggered from Signals,
348+
// or if there is hooks state, update:
349+
if (this._updateFlags & (HAS_PENDING_UPDATE | HAS_HOOK_STATE)) return true;
350+
}
351+
341352
// if any non-Signal props changed, update:
342353
for (let i in props) {
343354
if (i !== "__source" && props[i] !== this.props[i]) return true;

‎packages/preact/src/internal.d.ts

+5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ export interface AugmentedElement extends HTMLElement {
1818
}
1919

2020
export interface AugmentedComponent extends Component<any, any> {
21+
// hasScuFromHooks
22+
// Preact 10.12 - Preact 10.25
23+
u?: boolean;
24+
// Preact 10.26 and onwards
25+
__f?: boolean;
2126
__v: VNode;
2227
_updater?: Effect;
2328
_updateFlags: number;

0 commit comments

Comments
 (0)
Please sign in to comment.