Reactive Data
Useful Links
Actions
Table Demo
Name | Age | Phone | |
---|---|---|---|
Kendra Weissnat-Ziemann | 41 | Lucious23@hotmail.com | (852) 838-0609 |
Eleanor Hirthe | 28 | Dion38@gmail.com | (279) 388-6308 |
Helen Nolan | 22 | Casimir.Stokes@gmail.com | (618) 580-1053 |
Richard Bartell-Conn | 36 | Adolf51@gmail.com | (359) 280-6211 |
Hubert Gorczany | 84 | Madaline27@hotmail.com | (444) 771-0168 |
Clint Jenkins | 89 | Linnie22@hotmail.com | (796) 471-3480 |
Mr. Melvin Leuschke-MacGyver | 66 | Ressie.Smith@yahoo.com | (383) 241-5706 |
Eddie Dickens IV | 32 | Tad18@yahoo.com | (698) 637-5272 |
Christian Conroy | 77 | Irwin.Lubowitz@gmail.com | (601) 550-2439 |
Earnest West | 83 | Garrett_Crist@hotmail.com | (761) 925-7502 |
Explanation
In this guide, we'll extend your knowledge of creating a table in Svelte by focusing on handling reactive data.
Before proceeding, you should already know how to create and render a basic table.
Adding Data to a $state
Rune
The first step is to make the data reactive by storing it in a $state
. In
Svelte 5, $state
is a signal that allows you to track and update state changes
in a reactive manner. This ensures that when the data changes, the table will
automatically update to reflect those changes.
<script lang="ts">
type Props = {
data: PageData;
};
let { data }: Props = $props();
let { userProfiles } = data;
// Create a reactive state for the user profiles data using a $state rune.
let dataState = $state(userProfiles);
</script>
Creating the Table
To make the table reactive, we need to pass the data
property as a getter
function to createSvelteTable
. This approach ensures that the table
dynamically responds to changes in dataState
.
<script lang="ts">
import { type UserProfile } from '$lib/services/user-profile';
import { createColumnHelper, createSvelteTable, getCoreRowModel } from '$lib/table';
type Props = {
data: PageData;
};
let { data }: Props = $props();
let { userProfiles } = data;
let dataState = $state(userProfiles);
const colHelp = createColumnHelper<UserProfile>();
const columnDefs = [
colHelp.accessor('name', { header: 'Name' }),
colHelp.accessor('age', { header: 'Age' }),
colHelp.accessor('email', { header: 'Email' }),
colHelp.accessor('phone', { header: 'Phone' })
];
const table = createSvelteTable({
// The data field is defined as a getter to ensure it is reactive.
get data() {
return dataState;
},
columns: columnDefs,
getCoreRowModel: getCoreRowModel()
});
</script>
- Reactive Data: By implementing the
data
property as a getter, any change todataState
will automatically trigger the table to re-render with the updated data. - Benefit: This setup makes the table's data handling straightforward and automatically keeps it in sync with state changes.
Mutating Data
We will create two functions to modify the table data: one to add a record at
the beginning and another to remove the last record. It's crucial to reassign
the dataState
variable when updating the data to ensure reactivity.
<script lang="ts">
import { type UserProfile } from '$lib/services/user-profile';
import { createColumnHelper, createSvelteTable, getCoreRowModel } from '$lib/table';
type Props = {
data: PageData;
};
let { data }: Props = $props();
let { userProfiles } = data;
let dataState = $state(userProfiles);
const colHelp = createColumnHelper<UserProfile>();
const columnDefs = [
colHelp.accessor('name', { header: 'Name' }),
colHelp.accessor('age', { header: 'Age' }),
colHelp.accessor('email', { header: 'Email' }),
colHelp.accessor('phone', { header: 'Phone' })
];
const table = createSvelteTable({
get data() {
return dataState;
},
columns: columnDefs,
getCoreRowModel: getCoreRowModel()
});
function prependRecord() {
dataState = [UserProfileService.getOne(), ...dataState];
}
function popRecord() {
dataState = dataState.slice(0, dataState.length - 1);
}
</script>
<div class="actions-wrapper">
<h2>Actions</h2>
<hr />
<button onclick={() => prependRecord()}> Prepend a Record </button>
<button onclick={() => popRecord()}> Pop a Record </button>
</div>
🗒️ Note: The
dataState
variable must be reassigned after mutation (dataState = ...
) to ensure that the change is detected and triggers an update in the UI.
Rendering the Table in the Markup
Finally, we render the table using Svelte's templating syntax. Since the table
data is reactive, it will automatically update when you modify dataState
using
the functions created above.
<table>
<thead>
<tr>
{#each table.getHeaderGroups() as headerGroup}
{#each headerGroup.headers as header}
<th>
<FlexRender content={header.column.columnDef.header} context={header.getContext()} />
</th>
{/each}
{/each}
</tr>
</thead>
<tbody>
{#each table.getRowModel().rows as row}
<tr>
{#each row.getVisibleCells() as cell}
<td>
<FlexRender content={cell.column.columnDef.cell} context={cell.getContext()} />
</td>
{/each}
</tr>
{/each}
</tbody>
</table>