Skip to content

2.0.0-beta.14 email goes pending only when editing name #2747

@brenelz

Description

@brenelz

Solid 2 Pending State Issue

We are running into a Solid 2 beta issue involving isPending, latest, and a memoized optimistic store object.

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

Problematic Pattern

const user = createMemo(() => store.user);

isPending(() => latest(() => user().email));

Expected Behavior

If only store.user.name is optimistically changed, email should stay not pending.

This should behave the same as direct store access:

isPending(() => latest(() => store.user.email));

Actual Behavior

After modifying name and then calling refresh(store), email reports pending only through the memoized object path:

isPending(() => latest(() => user().email));

Direct store access does not show the false pending state:

isPending(() => latest(() => store.user.email));

Root Cause

createMemo(() => store.user) introduces an intermediate reactive source whose value is the whole user object.

During isPending(() => latest(...)), Solid collects pending sources from the read path. The memoized object source is collected in addition to the final email field.

When refresh(store) runs, the optimistic store's firewall/projection is pending. That intermediate object source sees the refresh pending state, so email incorrectly appears pending even though the email leaf was not updated.

App-Level Fix

Avoid memoizing store objects when precise field-level pending state is needed. Memoize/read the leaf property instead:

const name = createMemo(() => store.user.name);
const email = createMemo(() => store.user.email);

isPending(() => latest(name));
isPending(() => latest(email));

Or use direct store access:

isPending(() => latest(() => store.user.email));

Takeaway

Avoid memoizing store objects if you need precise field-level pending state. Memo or read the leaf property instead.

The likely framework-level bug is that isPending + latest should treat the intermediate memo object as transparent and only count the final leaf source.

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