Skip to content

Keyed client layer (source xs key id = q.rows) replaces every row object on each answer (IMMUTABLE_UPDATE_IN_STORE) #51

Closed

Description

@revosw

Filed with Opus 5.5. I personally don't have the required understanding to know whether it's something worth fixing, but I had a stab at converting my web app to use reactivescript. Very excited for the development, so I'll continue to file (hopefully) useful issues, based on the migration efforts

Versions: 0.1.0 and main at 08255de, solid-js 2.0.0-rc.21.

source xs key id = q.rows lowers to createOptimisticStore(draft => assignDraft(draft, …), [], { key }). For arrays, assignDraft does draft.length = v.length; v.forEach((x, i) => { draft[i] = x }), so every row is replaced by a fresh object on every answer. That includes a refresh that returns identical data.

Solid's dev runtime warns for each row:

[IMMUTABLE_UPDATE_IN_STORE] "store.0" was replaced with a fresh object whose leaves are mostly the same values (15 of 19 unchanged, 4 changed) — … For data arriving from outside (a fetch result), merge it with reconcile(data, key)(store.0).

Effect: what renders is correct, but every reader of every row re-runs on every answer. In our app (a booking grid with one keyed source of bookings) that means every card re-renders on each refresh and after each save.

Suggestion: merge the answer by the declared key, e.g. reconcile(v, key)(draft), as the warning recommends, instead of assigning rows. I haven't tested whether returning the value from the derive (letting Solid diff it by key) works equally well here.

Activity

  1. added a commit that references this issue on Nov 13, 2026
  2. ryansolid commented on Nov 13, 2026

    @ryansolid
    Member

    Thanks, confirmed. A keyed source that takes a guess now merges each answer by key, so a row whose key stays keeps its object and takes only the changed leaves, and its readers no longer re-run on every refresh. Fixed in #63.

    You asked about returning the value from the derive. That's the cleaner fix, but on the published Solid 2.0.0-rc.21 it hits an internal Solid error (already fixed on Solid's next). For now the runtime merges by key itself, and #64 tracks switching to the return path once rc.22 is out.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions