Loading state
Set progressPending to true while your data is in-flight.
DataTable adapts its loading UI based on whether rows are already visible:
- Initial load (no data yet): shimmer skeleton rows fill the body so the layout doesn't collapse.
- Re-fetch (rows already shown): existing rows stay in place, dim to 40% opacity, and a spinner overlays the centre. The header and pagination never disappear.
Loading state
Click either button to see the two loading modes.
Name
Department
Salary
Status
import { useState, useEffect } from 'react';
import DataTable from 'react-data-table-component';
export default function UsersTable() {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true); // true on first render → skeleton immediately
useEffect(() => {
fetch('/api/users')
.then(r => r.json())
.then(json => { setData(json.rows); setLoading(false); });
}, []);
function refresh() {
setLoading(true); // has existing rows → overlay mode
fetch('/api/users')
.then(r => r.json())
.then(json => { setData(json.rows); setLoading(false); });
}
return <DataTable columns={columns} data={data} progressPending={loading} />;
} Custom spinner or message
The default progressComponent is a CSS spinner circle. Pass any React node to replace it.
It will be centred in the overlay during re-fetches, or shown instead of skeletons on initial load.
<DataTable
progressPending={loading}
progressComponent={<MyBrandSpinner size={40} />}
/> Empty state
When progressPending is false and data is empty,
the noDataComponent is shown instead.
<DataTable
data={[]}
progressPending={false}
noDataComponent={<p>No results match your search.</p>}
/> Header visibility
The column header always stays visible during progressPending.
Use persistTableHead to also keep it visible when data is empty and not loading.
// Keep header visible when data is empty (e.g. after a filter returns nothing)
<DataTable persistTableHead data={[]} columns={columns} />