Skip to content

[Svelte] Client-side paginatedRowModel doesn't recompute when pagination state is externally controlled via state.pagination + onPaginationChange #6374

Description

@frenandre

TanStack Table version

v9.0.0-beta.29

Framework/Library version

@sveltejs/kit 2.69.1

Describe the bug and the steps to reproduce it

Describe the bug

When pagination state is externally controlled (v8-style state.pagination + onPaginationChange, or the new createTableState helper), table.getState().pagination.pageIndex updates correctly, but table.getRowModel().rows never reflects the new page — it always shows the rows from pageIndex: 0.

The identical pattern works correctly for sorting (state.sorting + onSortingChange), so this appears isolated to paginatedRowModel specifically.

Using manualPagination: true (server-side pagination, no client-side paginatedRowModel slicing) works correctly — the bug only affects client-side pagination.

Your minimal, reproducible example

<script lang="ts">
  import {
    createTable,
    createTableState,
    tableFeatures,
    rowPaginationFeature,
    createPaginatedRowModel,
    type PaginationState,
  } from '@tanstack/svelte-table'

  const features = tableFeatures({
    rowPaginationFeature,
    paginatedRowModel: createPaginatedRowModel(),
  })

  const [pagination, setPagination] = createTableState<PaginationState>({
    pageIndex: 0,
    pageSize: 15,
  })

  let list = $state(/* e.g. 250 rows */)

  const table = createTable({
    features,
    columns,
    get data() {
      return list
    },
    state: {
      get pagination() {
        return pagination()
      },
    },
    onPaginationChange: (updater) => {
      setPagination(updater) // <-- presence of this alone breaks getRowModel()
    },
  })
</script>

<!-- table.nextPage() correctly updates table.getState().pagination.pageIndex to 1,
     but table.getRowModel().rows still shows the same 15 rows as page 0 -->
<button onclick={() => table.nextPage()}>Next</button>

Steps to reproduce

  1. Create a table with rowPaginationFeature + createPaginatedRowModel(), more data than fits on one page (e.g. 250 rows, pageSize: 15).
  2. Control pagination externally via state.pagination + onPaginationChange (tested both with a raw Svelte $state object and with createTableState).
  3. Click "next page" (table.nextPage() or table.setPageIndex(n)).
  4. Observe table.getState().pagination.pageIndex — it updates correctly.
  5. Observe table.getRowModel().rows — it does not change; the same rows from page 0 keep being returned.

Expected behavior

table.getRowModel().rows should reflect the current pageIndex/pageSize, the same way it does when the table manages pagination internally (no state.pagination/onPaginationChange provided) or the same way sortedRowModel reacts to externally-controlled sorting.

How often does this bug happen?

Every time, 100% reproducible.

Platform

  • Version of TanStack Table: 9.0.0-beta.29
  • Framework: Svelte 5 (Runes mode)

Additional context

  • Confirmed this is not a $state/proxy-identity issue on the app side: tested both a raw let pagination = $state({...}) and createTableState<PaginationState>(...), identical behavior in both cases.
  • The identical pattern (state.sorting + onSortingChange) works correctly, so this seems isolated to the pagination row model's memoization/dependency tracking specifically.
  • The equivalent v8 configuration (state.pagination + onPaginationChange, getPaginationRowModel: getPaginationRowModel()) works correctly — this is a regression relative to v8 behavior.
  • Workaround currently in use: let the table manage pagination state fully internally (no state.pagination/onPaginationChange), and observe page changes passively via an effect on table.getState().pagination.pageIndex to drive side effects (e.g. resetting a selected-row index).

Your Minimal, Reproducible Example - (Sandbox Highly Recommended)


Screenshots or Videos (Optional)

No response

Do you intend to try to help solve this bug with your own PR?

None

Terms & Code of Conduct

  • I agree to follow this project's Code of Conduct
  • I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    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