Skip to content

{#each} block overwrites objects in state array #10387

@marc-eggers

Description

@marc-eggers

Describe the bug

First off: I'm not entirely sure this is a bug, so if I'm just misunderstanding some intended behaviour here, please let me know.

The src/routes/+page.svelte file in the reproduction repo contains a heavily simplified version of some state logic I've written in a project of mine. The rough breakdown of the setup is as follows:

  • The strat state is an object, which contains an array of steps. The demo contains 3 objects in steps.
  • Each step contains two arrays: players and stickies
  • The view state is an object with a single number value: activeStep
  • The template has an {#each} block, iterating over strat.steps[view.activeStep].players
  • There are 3 buttons, which set view.activeStep to 0, 1, or 2 respectively

A possibly important note: The repro I've provided shows no issues in [email protected] and below. The issue starts appearing at version 5.0.0-next.18.

The presence of this {#each} block alone - nothing else is being done anywhere - leads to some very peculiar behaviour. First off, some definitions: I will be referring to the step active on page load as "initial step", and the one targeted by view.activeStep as "current step".

  • When switching the current step using one of the buttons, the objects in players of the step being activated overwrite those found in the initial step. (The demo only contains a single player object for brevity, but if there are more, all objects in the array get overwritten).
  • For example, when the initial step is 0, and you switch to step 2, the objects in 0 get overwritten and are identical to those in 2. You can tell by the activePlayer.fromStep output in the "UI".
  • If you switch to step 1 after that, the objects in step 0 are now those of step 1.
  • Switching back to 0 does not revert this.
  • If you switch the data source of the {#each} block to stickies instead, you will observe the exact same behaviour, but with the stickies objects, instead.
  • The arrays themselves do not share an identity, only the objects within.

I hope this was a decent description of the issue I encountered. Let me know if there are any questions.

Reproduction

https://stackblitz.com/~/github.com/marc-eggers/svelte-5-bug-repro

Logs

No response

System Info

System:
    OS: macOS 13.2.1
    CPU: (8) arm64 Apple M1
    Memory: 85.89 MB / 8.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 18.16.1 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 9.5.1 - /usr/local/bin/npm
    pnpm: 7.18.2 - ~/Library/pnpm/pnpm
  Browsers:
    Chrome: 121.0.6167.139
    Safari: 16.3
  npmPackages:
    svelte: ^5.0.0-next.45 => 5.0.0-next.45

Severity

blocking an upgrade

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions