Tracking Array Changes in LWC Effectively
Table Of Contents
In Lightning Web Components (LWC), tracking changes in reactive properties like arrays and complex objects can be tricky. The framework only detects changes if the property reference is updated. Simply modifying the content of an array or an object does not change its reference, and thus, LWC won’t detect any updates to re-render the component.
This limitation arises because JavaScript stores arrays and objects as references in memory. When you modify their content without altering their reference, LWC does not register the change. This is particularly important when dealing with components like lightning-datatable, where the data displayed depends on a tracked array.
Problem Statement
Suppose you have a lightning-datatable displaying a list of objects. You want to add or remove rows dynamically and reflect these changes in the table. If you update the array using methods like push() or pop(), the component does not refresh because the array’s reference remains unchanged.
Here’s the example scenario:
HTML (Template):
<template>
<h1>Dynamic Datatable</h1>
<lightning-datatable
key-field="id"
data={data}
columns={columns}
is-loading={tableLoadingState}>
</lightning-datatable>
<lightning-button
label="Add Row"
variant="brand"
onclick={addRow}>
</lightning-button>
</template>JavaScript (Controller):
import { LightningElement, track } from 'lwc';
const columns = [
{ label: 'Name', fieldName: 'name', type: 'text' },
{ label: 'Website', fieldName: 'website', type: 'text' },
{ label: 'Phone', fieldName: 'phone', type: 'text' }
];
export default class DynamicTable extends LightningElement {
@track data = [
{ id: 1, name: 'John Doe', website: 'example.com', phone: '1234567890' }
];
columns = columns;
tableLoadingState = false;
addRow() {
const newRow = { id: this.data.length + 1, name: 'Jane Doe', website: 'test.com', phone: '0987654321' };
// Update the array with a new reference
this.data = [...this.data, newRow];
}
}Solution Explanation
In the addRow method, instead of directly modifying the array using push(), we create a new array using the spread operator ([...this.data, newRow]). This creates a new reference for the data property, which LWC tracks. Assigning this new array to data ensures that LWC detects the change and triggers a re-render of the lightning-datatable.
Handling Row Deletion
Similarly, if you want to remove a row, you should also create a new array reference. For example:
removeRow(rowId) {
this.data = this.data.filter(row => row.id !== rowId);
}Here, the filter() method creates a new array by excluding the row with the given rowId. The new array reference is then assigned to the data property, ensuring LWC re-renders the datatable.
Why Is This Necessary?
The LWC reactive system is optimized to detect changes through reference comparison. When you update the contents of an array or object without changing its reference, LWC does not detect the change. By assigning a new array or object reference, you enable LWC to recognize the update and refresh the UI accordingly.
Key Considerations
- Always create a new reference for tracked arrays and objects when updating their content.
- Use array methods like
map(),filter(), or the spread operator to create a new reference while preserving the existing data. - Avoid directly mutating tracked properties, as this does not trigger LWC’s reactivity system.
These practices ensure your LWC components behave as expected and efficiently handle updates to reactive properties.
Summing Up
In Lightning Web Components, I’ve learned that tracking changes in arrays and complex objects requires creating a new reference for the property. Simply modifying the content won’t work because LWC relies on reference changes to detect updates. By using techniques like the spread operator or methods like filter() and map(), I can ensure that updates to arrays or objects are recognized, triggering the component to re-render. This approach is essential for dynamic components like lightning-datatable, where maintaining accurate and responsive data display is crucial.

