@ipxjs/refract 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -52,6 +52,7 @@ export function renderFiber(vnode: VNode, container: Node): void {
|
|
|
52
52
|
isRendering = false;
|
|
53
53
|
const committedDeletions = deletions.slice();
|
|
54
54
|
commitRoot(rootFiber);
|
|
55
|
+
clearAlternates(rootFiber);
|
|
55
56
|
runAfterCommitHandlers();
|
|
56
57
|
roots.set(container, rootFiber);
|
|
57
58
|
runCommitHandlers(rootFiber, committedDeletions);
|
|
@@ -309,6 +310,17 @@ function setRef(ref: unknown, value: Node | null): void {
|
|
|
309
310
|
}
|
|
310
311
|
}
|
|
311
312
|
|
|
313
|
+
/** Release alternate references after commit to prevent memory leaks.
|
|
314
|
+
* Alternates are only needed during reconciliation; retaining them
|
|
315
|
+
* creates an ever-growing chain of old fiber trees. */
|
|
316
|
+
function clearAlternates(fiber: Fiber | null): void {
|
|
317
|
+
while (fiber) {
|
|
318
|
+
fiber.alternate = null;
|
|
319
|
+
if (fiber.child) clearAlternates(fiber.child);
|
|
320
|
+
fiber = fiber.sibling;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
312
324
|
function commitDeletion(fiber: Fiber): void {
|
|
313
325
|
runCleanups(fiber);
|
|
314
326
|
// Clear ref on unmount
|
|
@@ -406,6 +418,7 @@ function flushRenders(): void {
|
|
|
406
418
|
isRendering = false;
|
|
407
419
|
const committedDeletions = deletions.slice();
|
|
408
420
|
commitRoot(newRoot);
|
|
421
|
+
clearAlternates(newRoot);
|
|
409
422
|
runAfterCommitHandlers();
|
|
410
423
|
roots.set(container, newRoot);
|
|
411
424
|
runCommitHandlers(newRoot, committedDeletions);
|
|
@@ -75,8 +75,10 @@ export function useEffect(effect: () => EffectCleanup, deps?: unknown[]): void {
|
|
|
75
75
|
hook.state.deps = deps;
|
|
76
76
|
hook.state.pending = true;
|
|
77
77
|
markPendingEffects(fiber);
|
|
78
|
-
} else {
|
|
79
|
-
|
|
78
|
+
} else if (hook.state.pending) {
|
|
79
|
+
// Re-render before effect was flushed — keep it pending and
|
|
80
|
+
// re-register the fiber so the deferred flush still finds it.
|
|
81
|
+
markPendingEffects(fiber);
|
|
80
82
|
}
|
|
81
83
|
}
|
|
82
84
|
}
|
|
@@ -94,8 +96,8 @@ export function useLayoutEffect(effect: () => EffectCleanup, deps?: unknown[]):
|
|
|
94
96
|
hook.state.deps = deps;
|
|
95
97
|
hook.state.pending = true;
|
|
96
98
|
markPendingLayoutEffects(fiber);
|
|
97
|
-
} else {
|
|
98
|
-
|
|
99
|
+
} else if (hook.state.pending) {
|
|
100
|
+
markPendingLayoutEffects(fiber);
|
|
99
101
|
}
|
|
100
102
|
}
|
|
101
103
|
}
|
|
@@ -113,8 +115,8 @@ export function useInsertionEffect(effect: () => EffectCleanup, deps?: unknown[]
|
|
|
113
115
|
hook.state.deps = deps;
|
|
114
116
|
hook.state.pending = true;
|
|
115
117
|
markPendingInsertionEffects(fiber);
|
|
116
|
-
} else {
|
|
117
|
-
|
|
118
|
+
} else if (hook.state.pending) {
|
|
119
|
+
markPendingInsertionEffects(fiber);
|
|
118
120
|
}
|
|
119
121
|
}
|
|
120
122
|
}
|
|
@@ -33,14 +33,16 @@ function cleanupFiberEffects(fiber: Fiber): void {
|
|
|
33
33
|
if (!fiber.hooks) return;
|
|
34
34
|
|
|
35
35
|
for (const hook of fiber.hooks) {
|
|
36
|
-
const state = hook.state
|
|
37
|
-
if (state
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
const state = hook.state;
|
|
37
|
+
if (!state || typeof state !== "object") continue;
|
|
38
|
+
const effectState = state as { cleanup?: () => void; pending?: boolean };
|
|
39
|
+
if (effectState.cleanup) {
|
|
40
|
+
effectState.cleanup();
|
|
41
|
+
effectState.cleanup = undefined;
|
|
40
42
|
}
|
|
41
43
|
// Prevent deferred passive effects from running on unmounted fibers
|
|
42
|
-
if (
|
|
43
|
-
|
|
44
|
+
if ("pending" in effectState) {
|
|
45
|
+
effectState.pending = false;
|
|
44
46
|
}
|
|
45
47
|
}
|
|
46
48
|
}
|