---
product: "AG Grid"
title: "Client-Side Data - Single Row / Cell Updates"
description: "You can target updates to a single row or cell. Updating a single row means asking the grid to replace the data item for one specific row. Updating a cell means keeping the data item but asking the grid to replace one attribute of that data item."
framework: react
version: "36.2.0"
related:
    - title: "Row Data"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/data-update-row-data/"
    - title: "Transactions"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/data-update-transactions/"
    - title: "High Frequency"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/data-update-high-frequency/"
llms: "https://www.ag-grid.com/archive/36.2.0/llms.txt"
---

# Client-Side Data - Single Row / Cell Updates

You can target updates to a single row or cell. Updating a single row means asking the grid to replace the data item for one specific row. Updating a cell means keeping the data item but asking the grid to replace one attribute of that data item.

Both single row and single cell updates are done by first getting a reference to the row's Row Node and then using the relevant Row Node API method. See [Accessing Data](https://www.ag-grid.com/archive/36.2.0/react-data-grid/accessing-data/) on how to access Row Nodes. Once you have access to the required Row Node, you can update its data with the following Row Node API methods:

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `updateData` | `Function` |  |  |  |
| `setData` | `Function` |  |  |  |
| `setDataValue` | `Function` |  |  |  |
| `getDataValue` | `Function` |  |  |  |

## Reading Cell Values

There are two ways to read cell values:

- **`rowNode.getDataValue(colKey)`** — returns the underlying data value for a column. This includes resolved valueGetters, aggregation on group rows, and computed formulas, but excludes any pending edits. Use this when you need the raw data (e.g. for calculations or external updates).
- **`api.getCellValue({ rowNode, colKey })`** — returns the display value as shown in the grid, including pending edits and group column display logic. Pass `useFormatter: true` to get the formatted string. Use this when you need the value as the user sees it.

Both methods accept an optional `from` parameter to control how pending edits are resolved — see [Batch Editing - Reading Values](https://www.ag-grid.com/archive/36.2.0/react-data-grid/cell-editing-batch/#reading-values) for details.

## View Refresh

After calling `rowNode.setData`, `rowNode.updateData` or `rowNode.setDataValue`, the grid's view automatically refreshes to reflect the change. There is no need to manually request a refresh.

The main difference between `setData` and `updateData` is that `setData` always refreshes every cell, whereas `updateData` only refreshes cells whose values have changed. Additionally, `setData` does not cause changed cells to flash when `ColDef.enableCellChangeFlash = true`.

## Sort / Filter / Group Refresh

After calling `rowNode.setData`, `rowNode.updateData` or `rowNode.setDataValue` the grid does not update to reflect a change in sorting, filtering or grouping.

To have the grid update its sort, filter or grouping call the Grid API `refreshClientSideRowModel()`.

If you want the grid to automatically update sorting, filter or grouping then you should consider using [Transaction Updates](https://www.ag-grid.com/archive/36.2.0/react-data-grid/data-update-transactions/).

## Updating Rows / Cells Example

The example below demonstrates the following:

- **Set Price on Toyota:** The price value is updated on the Toyota row and the grid refreshes the cell.
- **Set Data on Ford:** The entire data is set on the Ford row and the grid refreshes the entire row. Updated cells do not flash (even though `enableCellChangeFlash = true`).
- **Update Data on Ford:** The entire data is updated on the Ford row and the grid refreshes the changed values in the row. Updated cells flash (as `enableCellChangeFlash = true`).
- **Sort:** Re-runs the sort in the Client-Side Row Model - to see this in action, sort the data first, then edit the data so the sort is broken, then hit this button to fix the sort.
- **Filter:** Re-runs the filter in the Client-Side Row Model - to see this in action, filter the data first, then edit the data so the filter is broken (i.e. a row is present that should not be present), then hit this button to fix the filter.

#### Updating Row Nodes

```tsx
"use client";

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import "./styles.css";
import {
  ClientSideRowModelApiModule,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GetRowIdFunc,
  GetRowIdParams,
  GridApi,
  GridOptions,
  HighlightChangesModule,
  ModuleRegistry,
  NumberEditorModule,
  NumberFilterModule,
  RowApiModule,
  TextEditorModule,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableDevValidations();
}

const modules = [
  ClientSideRowModelApiModule,
  RowApiModule,
  TextEditorModule,
  TextFilterModule,
  HighlightChangesModule,
  ClientSideRowModelModule,
  NumberFilterModule,
  NumberEditorModule,
];

function generateNewFordData() {
  const newPrice = Math.floor(window.agRandom() * 100000);
  const newModel = "T-" + Math.floor(window.agRandom() * 1000);
  return {
    id: "bb",
    make: "Ford",
    model: newModel,
    price: newPrice,
  };
}

const GridExample = () => {
  const gridRef = useRef<AgGridReact>(null);
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
  const [rowData, setRowData] = useState<any[]>([
    { id: "aa", make: "Toyota", model: "Celica", price: 35000 },
    { id: "bb", make: "Ford", model: "Mondeo", price: 32000 },
    { id: "cc", make: "Porsche", model: "Boxster", price: 72000 },
    { id: "dd", make: "BMW", model: "5 Series", price: 59000 },
    { id: "ee", make: "Dodge", model: "Challanger", price: 35000 },
    { id: "ff", make: "Mazda", model: "MX5", price: 28000 },
    { id: "gg", make: "Horse", model: "Outside", price: 99000 },
  ]);
  const [columnDefs, setColumnDefs] = useState<ColDef[]>([
    { field: "make" },
    { field: "model" },
    { field: "price", filter: "agNumberColumnFilter" },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      flex: 1,
      editable: true,
      filter: true,
      enableCellChangeFlash: true,
    };
  }, []);
  const getRowId = useCallback((params: GetRowIdParams) => {
    return params.data.id;
  }, []);

  const updateSort = useCallback(() => {
    gridRef.current!.api.refreshClientSideRowModel("sort");
  }, []);

  const updateFilter = useCallback(() => {
    gridRef.current!.api.refreshClientSideRowModel("filter");
  }, []);

  const setPriceOnToyota = useCallback(() => {
    const rowNode = gridRef.current!.api.getRowNode("aa")!;
    const newPrice = Math.floor(window.agRandom() * 100000);
    rowNode.setDataValue("price", newPrice);
  }, []);

  const setDataOnFord = useCallback(() => {
    const rowNode = gridRef.current!.api.getRowNode("bb")!;
    const newData = generateNewFordData();
    rowNode.setData(newData);
  }, []);

  const updateDataOnFord = useCallback(() => {
    const rowNode = gridRef.current!.api.getRowNode("bb")!;
    const newData = generateNewFordData();
    rowNode.updateData(newData);
  }, []);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div className="example-wrapper">
          <div style={{ marginBottom: "1rem" }}>
            <button onClick={setPriceOnToyota}>Set Price on Toyota</button>
            <button onClick={setDataOnFord}>Set Data on Ford</button>
            <button onClick={updateDataOnFord}>Update Data on Ford</button>
            <button onClick={updateSort} style={{ marginLeft: "15px" }}>
              Sort
            </button>
            <button onClick={updateFilter}>Filter</button>
          </div>

          <div style={gridStyle}>
            <AgGridReact
              ref={gridRef}
              rowData={rowData}
              columnDefs={columnDefs}
              defaultColDef={defaultColDef}
              getRowId={getRowId}
            />
          </div>
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Updating Row Nodes](https://www.ag-grid.com/archive/36.2.0/examples/data-update-single-row-cell/updating-row-nodes/reactFunctionalTs/)
