Feeding it your data
Every data-driven component takes plain objects.
Two tiers
DataTable and the charts need no pre-transform — render and sortAccessor handle nested objects and nulls in place. Everything else is a one-line .map().
// No transform: raw snake_case rows with a nested object and a null
<DataTable
data={users}
rowKey="user_id"
columns={[
{ key: 'full_name', header: 'Name', sortable: true },
{
key: 'team',
header: 'Team',
render: (row) => row.team?.name ?? '-',
sortAccessor: (row) => row.team?.name ?? '',
},
]}
/>
// One line for a section
<FeatureGrid features={api.capabilities.map((c) => ({
id: c.id, title: c.headline, description: c.blurb,
}))} />Which prop takes the array
The name is domain-specific per component, so here is the lookup: data for charts and DataTable; items for FAQ, Stats, Testimonials, Breadcrumb and CommandPalette; options for Select, RadioGroup and Combobox; columns for DataTable (table columns) and Footer (link groups); and features, plans, logos, messages, steps for the components named after them.
List items fall back to keying on a content field. Real API data contains two reviews by the same author or two metrics labelled "Users", and duplicate keys make React mis-attach state across a reorder. Pass id and it cannot happen.