Skip to content

2.0.0-beta.14: Keyed reconcile does not notify key subscribers on pure trailing removal #2773

Description

@yumemi-thomas

Describe the bug

In Solid 2.0.0-beta.14, keyed reconcile(..., "id") can remove trailing array items without notifying subscribers that track the store's key/iteration shape.

The array length updates, but an effect that tracks Object.keys(list) does not rerun when the only change is removing items from the end of the array.

Your Example Website or App

https://stackblitz.com/edit/solidjs-templates-26rbhvab?file=src%2FApp.tsx

import { createRenderEffect, createStore, reconcile } from "solid-js";

export default function App() {
  const [list, setList] = createStore([{ id: 1 }, { id: 2 }, { id: 3 }]);

  createRenderEffect(
    () => Object.keys(list),
    nextKeys => {
      console.log("Object.keys effect:", nextKeys.join(","));
    }
  );

  return (
    <main>
      <button onClick={() => setList(reconcile([{ id: 1 }, { id: 2 }], "id"))}>
        remove trailing row
      </button>

      <p>length: {list.length}</p>
      <p>Open the console and watch the Object.keys effect logs.</p>
    </main>
  );
}

Steps to Reproduce the Bug or Issue

  1. Open the repro.
  2. Open the browser console.
  3. Observe the initial console log.
  4. Click remove trailing row.
  5. Observe the rendered length and the browser console logs.

Expected behavior

Removing the trailing row should notify subscribers that track the array's key/iteration shape.

On page load, the effect logs the initial keys:

Object.keys effect: 0,1,2

After clicking the button, the rendered length changes to 2, and the Object.keys(list) effect should run again because the array keys changed from 0,1,2 to 0,1.

Expected state after click:

length: 2
Object.keys effect: 0,1

Screenshots or Videos

No response

Platform

  • OS: macOS
  • Browser: Chrome
  • Version: current stable

Additional context

Actual behavior in the buggy version:

length: 2
Object.keys effect only logs once with 0,1,2

So reconcile does remove the item, and list.length updates correctly. The bug is specifically that the subscriber tracking Object.keys(list) is not notified for this pure trailing removal.

This appears related to packages/solid-signals/src/store/reconcile.ts in the keyed array reconciliation early-exit path for pure trailing removals. The length signal is updated, but the store's key/iteration tracking does not appear to be notified.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions