Server-side React guide

Build a server-side data grid in React

A server-backed grid is not just a large table. It is a query, cache, mutation, and failure protocol that must remain understandable while users filter, sort, edit, and navigate.

Open server row docs See Enterprise pricing

Define the query contract

Send an explicit range or cursor plus sort, filter, group, and projection state. Return stable row IDs, deterministic ordering, rows, total or continuation information, and a request identity. The server must apply all query operations to the same authoritative dataset.

Control cache and cancellation

Choose block size, prefetch distance, eviction, request deduplication, retry limits, and invalidation after edits. When filters or sorting change quickly, cancel or supersede older requests and ignore stale responses that arrive after the active query.

Return mutation outcomes by identity

Edits and bulk actions should return saved, rejected, conflicted, forbidden, or retryable outcomes keyed by stable row and field identity. Include the authoritative version so the grid can patch or invalidate affected blocks without leaving neighboring totals stale.

Test failure as a normal state

Test latency, timeout, cancellation, partial blocks, duplicate requests, permission changes, empty results, rate limits, retries, and records moving out of the active filter. Preserve useful context during refresh and make retry scope visible.

Product evidence

Enterprise server row model

Ace Grid Enterprise exposes server-backed row loading for remote sort, filter, group, page, and cache workflows while the viewport continues to virtualize mounted content.

Live Ace Grid example

Server-backed portfolio grid

Keep remote sort, filter, paging, grouping, and mutation state explicit.

Portfolio sliceTierControlARRGovernanceAction
Portfolio TotalEnterpriseLive$12.8m93%Pivot
North AmericaStrategicLive$5.4m88%Chart
EMEAEnterpriseReview$4.2m76%Detail
LATAMMarketEscalate$1.6m61%Server

Connect a server row model

import { Grid } from "@ace-grid/enterprise";

<Grid data={{ columns }} serverRowModel={{ enabled: true, blockSize: 200, getRows: (request) => fetch("/api/accounts/query", { method: "POST", body: JSON.stringify(request) }).then((response) => response.json()) }} />;

Limitations and tradeoffs

  • Client-side data is simpler when the complete working set is small and already available.
  • Do not add a server row model solely to compensate for expensive custom cell rendering.

Common questions

Does virtualization load data from the server?

No. Virtualization limits mounted UI. The server row model separately decides when and how remote blocks are requested.

How should stale responses be handled?

Attach identity to each query and ignore responses superseded by newer sort, filter, grouping, or paging state.

Sources