Make lwc:spread reactive

Volodymyr Radko
3 min readJun 19, 2023

With Salesforce Summer ’23 release, we got a new feature for LWC components called lwc:spread, which allows us to spread properties on child components. While the documentation explains how to use it, it's crucial to make the spread feature reactive to maximize its usability. In this article, we'll explore examples of a parent component and a nested child component to understand how to achieve reactivity.

Parent Component:

<template>
<lightning-card title='Spread test'>
<div>
<lightning-button
class='slds-m-left_medium'
label="Find Buttons"
variant="brand"
onclick={onButtonClick}
></lightning-button>
</div>
<div>
<c-spread-test-child lwc:spread={someProps}></c-spread-test-child>
</div>
</lightning-card>
</template>
import { LightningElement, track } from 'lwc';

export default class SpreadTest extends LightningElement {

@track someProps = {
childName: 'childName',
otherProperty: 1234,
};

onButtonClick(event) {
this.someProps.childName = 'childProps123235';
this.someProps.otherProperty = 9876;
}
}

Child Component:

<template>
<p>{childName}</p>
<p>{otherProperty}</p>
</template>
import { LightningElement, api } from 'lwc';

export default class SpreadTestChild extends LightningElement {

@api childName;
@api otherProperty;
}

When included in a layout, the component will look like this:

Reactivity Challenge:

If we try to click the button, the childName and 1234 in the child component will not be re-rendered compared to the regular parameter passing approach. The documentation provides an example where we can reassign a name, but we need to completely assign another object to the same variable. Let's modify the method:

onButtonClick(event) {
this.someProps.childName = 'childProps123235';
this.someProps.otherProperty = 9876;
this.someProps = {...this.someProps};
}

Hmm… Still nothing happens. Just to be clear, rewriting it like this works:

onButtonClick(event) {
this.someProps = { childName: 'childProps1234235', otherProperty: 9876};
}

However, this static approach is not dynamic enough for developers who would like more flexibility in changing parameters.

Finding Working Solutions:

We start from the example provided by Salesforce since it at least works, but we’ll try to modify it. Here’s what we have:

onButtonClick(event) {
this.someProps = {};
this.someProps.childName = 'childProps12355';
this.someProps.otherProperty = 9876;
}

This solution works, but what if someProps already contains important information?

Let’s explore other working solutions:

onButtonClick(event) {
const a = {...this.someProps};
a.childName = 'ABCD';
this.someProps = a;
}

This works! But let’s try something else:

onButtonClick(event) {
this.someProps = {...this.someProps};
this.someProps.childName = 'ABCD213';
}

Or even simpler:

onButtonClick(event) {
this.someProps = {...this.someProps, childName: 'ABCD!@!$%'};
}

In both cases, the property is re-rendered on the component. If we compare this with a similar example above that didn’t work, it’s a matter of putting the reassignment first before any data manipulations or using destructuring reassignment with the required parameters.

However, some solid approaches like Object.assign or JSON.parse(JSON.stringify(obj)) do not work:

onButtonClick(event) {
this.someProps.childName = 'xfhdfhdf';
this.someProps = Object.assign({}, this.someProps);
}
onButtonClick(event) {
this.someProps.childName = 'xfhdfhdf';
this.someProps = JSON.parse(JSON.stringify(this.someProps));
}

This behavior is not described in the documentation and is inconsistent. To make the spread operator reactive, you need to know these rules. Hopefully, it will be fixed or better explained in the near future, as this feature is truly great and can help manage child component parameters in a more elegant and efficient way.

Conclusion:

Reactivity is crucial when using the lwc:spread feature in LWC components. Although there are workarounds to achieve reactivity, the behavior and rules are not clearly documented. By understanding the correct approaches, developers can fully leverage the power of lwc:spread to enhance the management of child component parameters.

Happy coding, everyone!

--

--