React editable data grid

React editable data grid for operational workflows

An editable React data grid needs a defined transaction model: when values commit, where validation runs, how concurrent changes are detected, and how users recover from failed saves.

Open editing documentation Explore spreadsheet workflows

Choose an edit transaction model

Immediate saves need optimistic UI, request cancellation, server rejection handling, and row-version conflicts. Staged saves need dirty indicators, batch validation, review, partial failure behavior, and discard or rollback.

Validate at three layers

Use parsers and column validators for immediate feedback, Pro validation workflows for richer grid rules, and backend validation for authority. Never rely on the browser to enforce permissions or business invariants.

Protect identity and recovery

Use stable row IDs, include a version or ETag in writes, keep the failed user value visible, explain server errors at the affected cell or row, and provide a retry or reset path. Test concurrent edits with two sessions.

Handle concurrent changes

Include a row version or ETag in writes. When another user changes the same record, show which value is stale and let the user refresh, retry, or reconcile. Test a row moving out of the current filter after an edit, permissions changing during a session, and partial batch success. Stable row IDs are essential for attaching outcomes to the correct record.

Design permissions and protected fields

The server determines which users can edit each record and field. The grid can disable or hide editors for clarity, but client state is not enforcement. Recheck permission at commit time and return a specific outcome. Test permission changes during an open session and avoid exposing protected values through exports, clipboard, or validation messages.

Test bulk editing and failure recovery

Paste, fill, multi-row actions, and batch saves can affect many records. Define atomic versus partial behavior, validation summaries, progress, cancellation, retry, and rollback. Return outcomes keyed by stable row and column identity. Users should be able to correct rejected values without re-entering successful changes.

Product evidence

Editing APIs

GridColumn exposes editable, editorType, renderEditor, parser, formatter, validator, and validation configuration. Pro adds broader validation workflows and formulas.

Controlled cell updates with pending row state

import { useState } from "react";
import { Grid, type CellValue, type GridRow } from "@ace-grid/core";

export function EditableOrdersGrid({ initialRows, columns }) {
  const [rows, setRows] = useState<GridRow[]>(initialRows);
  const [pending, setPending] = useState(new Set<string>());

  const updateCell = (
    rowId: string | number,
    columnKey: string,
    value: CellValue,
  ) => {
    setRows((current) =>
      current.map((row) =>
        row.id === rowId
          ? { ...row, data: { ...row.data, [columnKey]: value } }
          : row,
      ),
    );
    setPending((current) => new Set(current).add(String(rowId)));
  };

  return (
    <Grid
      data={{ rows, columns }}
      columns={{ columnWidths: {}, fillWidth: true }}
      layout={{ width: 1200, height: 520 }}
      edit={{ isCellEditing: true, onCellChange: updateCell }}
      virtual={{ enableVirtualization: true }}
    />
  );
}

Limitations and tradeoffs

  • Use a form when people edit one record at a time and field-level guidance matters more than scanning comparable rows.
  • Do not allow grid edits until the application defines validation, save failure, permission, and conflict behavior.

Common questions

Should cell changes save immediately?

It depends on risk and backend behavior. Immediate saves fit independent low-risk fields; batch or approval flows fit related changes that must be reviewed together.

How should rejected edits appear?

Keep the attempted value and server message attached to the affected row and field, preserve focus, and offer retry or revert without discarding unrelated edits.

Sources