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} />