Keyed List Behavior

DOM++ does not include a virtual DOM reconciliation engine or automatic keyed diffing system.

Instead, list identity is preserved by reusing the same DOM node references directly.

Important

DOM++ preserves stateful list items by reusing existing DOM node references.

There is no hidden reconciliation pass.

Identity preservation depends entirely on:

Identity Preservation Pattern

// =====================================
// STATEFUL ITEM
// =====================================
function createItem(label) {
  return document
    .createElement("div")
    .setAttributes({
      class: "item"
    })
    .setState({
      count: 0
    })
    .setChildren(({
      state,
      setState
    }) => [
      // ===============================
      // TITLE
      // ===============================
      document
        .createElement("h3")
        .setText(
          `Item ${label}`
        ),

      // ===============================
      // COUNT
      // ===============================
      document
        .createElement("div")
        .setAttributes({
          class: "counter"
        })
        .setText(
          `${state.count}`
        ),

      // ===============================
      // BUTTON
      // ===============================
      document
        .createElement("button")
        .setText(
          "Increment"
        )
        .setEvents({
          click() {
            setState({
              count:
                state.count + 1
            });
          }
        })
    ]);
}

// =====================================
// INITIAL ITEMS
// =====================================
let items = [
  createItem("A"),
  createItem("B"),
  createItem("C")
];

// =====================================
// LIST ROOT
// =====================================
const list =
  document
    .createElement("div")
    .setAttributes({
      class: "list"
    })
    .setChildren(
      ...items
    );

// =====================================
// RENDER
// =====================================
function render() {
  list.setChildren(
    ...items
  );
}

// =====================================
// REVERSE
// =====================================
reverse.setEvents({
  click() {
    items.reverse();
    render();
  }
});

// =====================================
// SHUFFLE
// =====================================
shuffle.setEvents({
  click() {
    items.sort(() => {
      return Math.random() - 0.5;
    });
    render();
  }
});

// =====================================
// REPLACE
// =====================================
replace.setEvents({
  click() {
    items = [
      createItem("A"),
      createItem("B"),
      createItem("C")
    ];
    render();
  }
});

// =====================================
// APP
// =====================================
app.setChildren(
  list
);
Notes
  • DOM node references act as identity
  • local state remains attached to reused nodes
  • reordering preserved nodes preserves state
  • recreating nodes resets state

Live Preview