diff --git a/.changeset/short-radios-sneeze.md b/.changeset/short-radios-sneeze.md new file mode 100644 index 0000000000..847c3eef17 --- /dev/null +++ b/.changeset/short-radios-sneeze.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: read batch-local array on each-block commit diff --git a/packages/svelte/src/internal/client/dom/blocks/each.js b/packages/svelte/src/internal/client/dom/blocks/each.js index ea828f893b..58d59a6825 100644 --- a/packages/svelte/src/internal/client/dom/blocks/each.js +++ b/packages/svelte/src/internal/client/dom/blocks/each.js @@ -216,9 +216,6 @@ export function each(node, flags, get_collection, get_key, render_fn, fallback_f tag(each_array, '{#each ...}'); } - /** @type {V[]} */ - var array; - /** @type {Map>} */ var pending = new Map(); @@ -234,6 +231,11 @@ export function each(node, flags, get_collection, get_key, render_fn, fallback_f state.pending.delete(batch); + // The effect doesn't necessarily re-run in a batch right before that batch commits + // (its view of the collection may not have changed), so we read the collection + // as the committing batch sees it rather than using the most recent block run's result + var array = get(each_array); + state.fallback = fallback; reconcile(state, array, anchor, flags, get_key); @@ -264,7 +266,7 @@ export function each(node, flags, get_collection, get_key, render_fn, fallback_f } var effect = block(() => { - array = /** @type {V[]} */ (get(each_array)); + var array = /** @type {V[]} */ (get(each_array)); var length = array.length; /** `true` if there was a hydration mismatch. Needs to be a `let` or else it isn't treeshaken out */