[SalesForce] LWC best practices: Getters for derived values vs. setters for controlling values

I'm aware of two separate ways to manage dynamic, derived values in Lightning Web Components, and I'd like to get a better idea of when to use each one.

Here is a sample LWC: a repeatable row showing an item's name. The div element has a class that is derived from component's selected property.

<template>
    <div class={divClass}>
        {itemName}
    </div>
</template>

Method A

I have seen a lot of LWC code examples that recommend something like this for the JavaScript side:

import { LightningElement, api } from "lwc";

export default class MyCmp extends LightningElement {
    @api itemName;
    @api selected = false;

    get divClass() {
        return this.selected ? "selected" : "";
    }
}

I'm aware that Lightning Web Components re-render frequently, and depending on the complexity of the solution, the getter for divClass may be called many times over the component's lifecycle, even if selected has not changed.

Method B

An alternative approach would be to use a setter on selected.

import { LightningElement, api } from "lwc";

export default class MyCmp extends LightningElement {
    @api itemName;
    @api 
    set selected(value) {
        if (value !== this._selected) {
            this._selected = value;
            this.updateDivClass();
        }
    }
    _selected = false;
    divClass = "";

    updateDivClass() {
        this.divClass = this._selected ? "selected" : "";
    }
}

I think this approach may have performance benefits, since you don't have getter functions getting called right and left. divClass is a simple primitive. On the other hand, this is heavier code, and it gets even more complex when you're dealing values that are derived from multiple other values.

Does anyone else use Method B? If so, when do you feel it's justified/important to do so?

Best Answer

You should prefer method A. Hint: the system calls all getters and then checks against the previous version using === to decide what to redraw. Therefore, B doesn't actually perform any better than A, even though it feels like it should. The advantage of A is that you don't have to remember to call a special method every time you make a change. The platform does this for you. Of course, if using an Array or Object, remember that constructing a new one will cause slightly more work (the system has to recursively check for changes), but still shouldn't harm performance too much, as only changes are redrawn. There are advantages to using a setter, but mostly only in terms of applying some validation or logic from an @api attribute.

Related Topic