diff --git a/CHANGELOG.md b/CHANGELOG.md
index 26c50c86be..6e62f3973c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@
* Fix checkbox `bind:group` in keyed `{#each}` where the array can be reordered ([#5779](https://github.com/sveltejs/svelte/issues/5779))
* Fix checkbox `bind:group` in nested `{#each}` contexts ([#5811](https://github.com/sveltejs/svelte/issues/5811))
* Add graphics roles as known ARIA roles ([#5822](https://github.com/sveltejs/svelte/pull/5822))
+* Fix local transitions if a parent has a cancelled outro transition ([#5822](https://github.com/sveltejs/svelte/issues/5822))
## 3.31.0
diff --git a/src/compiler/compile/render_dom/wrappers/EachBlock.ts b/src/compiler/compile/render_dom/wrappers/EachBlock.ts
index 2c0f5f68b4..75db59161b 100644
--- a/src/compiler/compile/render_dom/wrappers/EachBlock.ts
+++ b/src/compiler/compile/render_dom/wrappers/EachBlock.ts
@@ -450,7 +450,7 @@ export default class EachBlockWrapper extends Wrapper {
this.block.maintain_context = true;
this.updates.push(b`
- const ${this.vars.each_block_value} = ${snippet};
+ ${this.vars.each_block_value} = ${snippet};
${this.renderer.options.dev && b`@validate_each_argument(${this.vars.each_block_value});`}
${this.block.has_outros && b`@group_outros();`}
diff --git a/test/js/samples/each-block-keyed-animated/expected.js b/test/js/samples/each-block-keyed-animated/expected.js
index 96e75c61d3..b48073f5a7 100644
--- a/test/js/samples/each-block-keyed-animated/expected.js
+++ b/test/js/samples/each-block-keyed-animated/expected.js
@@ -94,7 +94,7 @@ function create_fragment(ctx) {
},
p(ctx, [dirty]) {
if (dirty & /*things*/ 1) {
- const each_value = /*things*/ ctx[0];
+ each_value = /*things*/ ctx[0];
for (let i = 0; i < each_blocks.length; i += 1) each_blocks[i].r();
each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, each_1_anchor.parentNode, fix_and_destroy_block, create_each_block, each_1_anchor, get_each_context);
for (let i = 0; i < each_blocks.length; i += 1) each_blocks[i].a();
diff --git a/test/js/samples/each-block-keyed/expected.js b/test/js/samples/each-block-keyed/expected.js
index a01bec628b..7808ed677f 100644
--- a/test/js/samples/each-block-keyed/expected.js
+++ b/test/js/samples/each-block-keyed/expected.js
@@ -79,7 +79,7 @@ function create_fragment(ctx) {
},
p(ctx, [dirty]) {
if (dirty & /*things*/ 1) {
- const each_value = /*things*/ ctx[0];
+ each_value = /*things*/ ctx[0];
each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, each_1_anchor.parentNode, destroy_block, create_each_block, each_1_anchor, get_each_context);
}
},
diff --git a/test/runtime/samples/transition-js-each-outro-cancelled/_config.js b/test/runtime/samples/transition-js-each-outro-cancelled/_config.js
new file mode 100644
index 0000000000..9f9bd35f05
--- /dev/null
+++ b/test/runtime/samples/transition-js-each-outro-cancelled/_config.js
@@ -0,0 +1,57 @@
+export default {
+ html: '',
+ async test({ assert, component, target, raf }) {
+ await component.add();
+ await component.add();
+
+ let time = 0;
+
+ assert.htmlEqual(target.innerHTML, `
+
+ `);
+
+ raf.tick(time += 400);
+
+ assert.htmlEqual(target.innerHTML, `
+
+ `);
+
+ await component.toggle();
+ // transition halfway
+ raf.tick(time += 200);
+
+ assert.htmlEqual(target.innerHTML, `
+
+ `);
+
+ await component.toggle();
+ // transition back
+ raf.tick(time += 200);
+
+ assert.htmlEqual(target.innerHTML, `
+
+ `);
+
+ await component.remove(1);
+
+ raf.tick(time += 400);
+
+ assert.htmlEqual(target.innerHTML, `
+
+ `);
+ }
+};
diff --git a/test/runtime/samples/transition-js-each-outro-cancelled/main.svelte b/test/runtime/samples/transition-js-each-outro-cancelled/main.svelte
new file mode 100644
index 0000000000..7c08be492f
--- /dev/null
+++ b/test/runtime/samples/transition-js-each-outro-cancelled/main.svelte
@@ -0,0 +1,29 @@
+
+
+{#if shown}
+
+ {#each items as thing (thing._id)}
+ {thing.name}
+ {/each}
+
+{/if}