Live-updating data grid
A price ticker where rows briefly highlight when their value changes — the same pattern behind trading blotters and live ops dashboards. It's just three ingredients you already have:keyField to identify rows across updates, a small piece of state tracking which rows just changed, and conditionalRowStyles to flash them.
Live-updating price grid
Prices tick every ~1.2s. Rows flash briefly when their price changes.
import React, { useEffect, useState } from 'react';
import DataTable, { type ConditionalStyles, type TableColumn } from 'react-data-table-component';
interface Ticker {
symbol: string;
name: string;
price: number;
change: number;
}
const INITIAL: Ticker[] = [
{ symbol: 'ACME', name: 'Acme Corp', price: 182.4, change: 0 },
{ symbol: 'BLTC', name: 'Baltic Freight', price: 64.12, change: 0 },
{ symbol: 'CNDL', name: 'Candle Systems', price: 305.9, change: 0 },
{ symbol: 'DYNM', name: 'Dynamo Energy', price: 48.77, change: 0 },
{ symbol: 'EVRG', name: 'Evergreen Foods', price: 96.3, change: 0 },
];
const columns: TableColumn<Ticker>[] = [
{ id: 'symbol', name: 'Symbol', selector: r => r.symbol, sortable: true, width: '110px', style: { fontWeight: 600 } },
{ id: 'name', name: 'Name', selector: r => r.name, grow: 1 },
{
id: 'price',
name: 'Price',
selector: r => r.price,
right: true,
width: '110px',
format: r => `$${r.price.toFixed(2)}`,
},
{
id: 'change',
name: 'Change',
selector: r => r.change,
right: true,
width: '110px',
cell: r => (
<span className={r.change === 0 ? 'text-gray-400' : r.change > 0 ? 'text-green-600' : 'text-red-600'}>
{r.change === 0 ? '—' : `${r.change > 0 ? '▲' : '▼'} ${Math.abs(r.change).toFixed(2)}`}
</span>
),
},
];
export default function LiveUpdatesDemo() {
const [data, setData] = useState<Ticker[]>(INITIAL);
const [flashed, setFlashed] = useState<Set<string>>(new Set());
useEffect(() => {
const tick = setInterval(() => {
const symbol = INITIAL[Math.floor(Math.random() * INITIAL.length)].symbol;
const delta = +(Math.random() * 4 - 2).toFixed(2);
setData(prev =>
prev.map(r => (r.symbol === symbol ? { ...r, price: +(r.price + delta).toFixed(2), change: delta } : r)),
);
setFlashed(prev => new Set(prev).add(symbol));
setTimeout(
() =>
setFlashed(prev => {
const next = new Set(prev);
next.delete(symbol);
return next;
}),
600,
);
}, 1200);
return () => clearInterval(tick);
}, []);
const conditionalRowStyles: ConditionalStyles<Ticker>[] = [
{
when: r => flashed.has(r.symbol),
style: { backgroundColor: '#fefce8', transition: 'background-color 0.6s ease' },
},
];
return (
<div className="rounded-xl border border-gray-200 overflow-hidden">
<DataTable
columns={columns}
data={data}
keyField="symbol"
conditionalRowStyles={conditionalRowStyles}
highlightOnHover
dense
/>
</div>
);
}This demo uses Tailwind utility classes for layout — swap in your own CSS when copying into your project.
Match rows across updates with keyField
When data is replaced on every tick, React (and the table) need a stable identity per row. Set keyField to whichever field uniquely identifies a row:
<DataTable columns={columns} data={data} keyField="symbol" />Track which rows just changed
Keep a Set of recently-changed keys in state. Add a key when its row updates, then remove it after the flash duration:
const [flashed, setFlashed] = useState<Set<string>>(new Set());
function updatePrice(symbol: string, next: number) {
setData(prev => prev.map(r => (r.symbol === symbol ? { ...r, price: next } : r)));
setFlashed(prev => new Set(prev).add(symbol));
setTimeout(() => setFlashed(prev => {
const copy = new Set(prev);
copy.delete(symbol);
return copy;
}), 600);
}Flash the row with conditionalRowStyles
No animation library needed — a CSS transition on the inline style fades the highlight out on its own:
const conditionalRowStyles: ConditionalStyles<Ticker>[] = [
{
when: r => flashed.has(r.symbol),
style: { backgroundColor: '#fefce8', transition: 'background-color 0.6s ease' },
},
];
<DataTable columns={columns} data={data} keyField="symbol" conditionalRowStyles={conditionalRowStyles} />