Skip to content

Support for Stable ViewKeys to Prevent UI Re-renders on ID Mapping #19

@KyleAMathews

Description

@KyleAMathews

Problem

Currently, optimistic inserts use temporary IDs (tempid) until the server responds with the authoritative ID (realid). When the ID changes, React re-renders the keyed element, causing UI issues:

  • Focus loss
  • Component state reset
  • Input interruption
  • Flickering

Because React treats the key as identity, replacing the ID forces React to unmount and remount the component. In many cases this is acceptable, but in advanced usage (e.g., editable lists, interactive forms) it causes UX degradation.

Proposed Solution

Introduce optional developer control to maintain a stable viewKey that survives the tempid → realid mapping.

  • Each record will have a viewKey field generated at optimistic creation time.
  • viewKey remains constant across ID upgrades.
  • UI components should key off viewKey, not id, if stability is required.
  • Expose a manual API for developers to map tempid to realid in the persist function.

Example usage:

persist: (transaction) => {
  const result = api.insert(data);
  transaction.mapViewKey({ tempId: tempid, realId: result.id });
}
  • Mapping must occur after server success but before transaction completion.
  • System updates internal references.
  • No UI re-renders triggered by ID changes.
  • If no mapping is performed, fallback to current behavior (tempid replaced by realid, React re-renders).

Design Principles

  • Opt-in only. No automatic viewKey generation unless explicitly requested.
  • Defaults stay simple for developers who don't need stability.
  • Advanced users can maintain seamless UX where needed.
  • Keeps transaction model deterministic and explicit.

Future Work

  • Consider offering a helper to auto-generate viewKey at insert time if requested.
  • Potentially expose viewKey defaults in the collection or transaction configuration for convenience.

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