this.watch vs. on Mutate for handling changes in a backdraft watchable

21 Views Asked by At

In a backdraftjs component with watchable 'titleString', is there any difference/preference between

this.watch('titleString', this.handleTitleStringChange);

and

onMutateTitleString(newTitle, oldTitle) {
    ...
}

The onMutate has the benefit that it remembers the old value (oldTitle) but this.watch() is maybe a little easier to find in code since it contains the word titleString -- where for onMutate you have to know to search for the camelcased-and-concatenated version.

Are there any other reasons to use one or the other?

1

There are 1 best solutions below

2
On

Great question.

To begin...a minor clarification in the question: both methods are provided the new value and old value. See the docs for a watcher.

The main difference is that onMutateproperty-name is a member function. As such, it is unconditionally applied immediately after the actual mutation to the underlying memory slot occurs and before any watchers are applied. In essence, it is an extension of the framework's mutation machinery for a particular property in a particular class that contains the WatchHub mixin. It is used to define/enforce a behavior that is part of the definition of the class. As such, note also onMutateproperty-name can be overridden in subclasses (because, structurally, onMutateproperty-name is a method, and, heuristically, the behavior is part of what defines the mental model of the class).

All that said, it is certainly possible to accomplish most of what onMutateproperty-name does by simply connecting a watcher with the watch instance method...sans subclass override capability, and at the added expense of creating a watch handle and the rest.

On the other hand, connecting a watcher via a component's watch instance method is intended for use by clients of instances of the class. These connections typically should not result in mutating the instance state internally...if that was not true, then a particular instance would behave differently depending upon what clients had connected to its watch interface.

Of course, in JavaScript this is expensive to enforce and the library made the intentional decision to not construct enforcement machinery. This is a general principle of the library: encourage canonical design and implementation paradigms, but don't prevent the using engineer from doing what needs to be done (sometimes the world isn't perfect and we need to do what we need to do).