Disposal
Disposal in the Ownership guide.
Disposing an owner runs, in this order:
- its children, newest child first, each of them completely (their children first);
- its own cleanups, newest registered first.
Cleanups run untracked. A cleanup that throws does not stop the others; its error is routed to the owner (see errors).
An effect or memo that re-runs disposes what its previous run created before running again: first its children, then its own cleanups. That is why an effect that creates a root, a nested effect or a listener does not leak.
Disposal is iterative#
The depth of the owner tree is controlled by your application (nested lists inside nested branches), so disposal walks it with an explicit loop instead of recursion. A tree 50,000 levels deep disposes without a stack overflow, deepest first.
Disposal is an implicit batch#
Writes made by cleanups are batched: effects that depend on them run before dispose() returns, unless the disposal happens inside a computation, a batch or a flush (their own exit flushes). See the scheduler.