Following on from yesterday's investigations into the behaviour of '@track', and its effect on untracked properties, I figured I should expand my remit to '@wire'.
My main reason for that was the statement in the documentation:
This comment relates to code along the lines of:
@api recordId; @wire(getRecord, { recordId: '$recordId', fields }) contact;
The bit that really piqued my interest was 'The property is reactive'.
In all the examples, it looked like the property being referenced was always tracked or set as an api field (the latter implying the former)
That's the case in the above example - the property passed as a parameter 'recordId' as referenced by '$recordId' is defined as an api field, and is therefore tracked.
There's also that recurring point 'the component rerenders', which we saw in my previous post. Recalling that, it essentially meant that a change to a tracked property caused all untracked properties in the same component (and I am assured, but yet to prove, child components) to be re-rendered
So, what is the actual behaviour in this case? Are the implications the same?
Tracked property used as a parameter to a wired property
The natural first example is much like the one exampled above. We have an Apex method that takes a parameter. We wire that parameter to a javascript property, and reference a single parameter.
Javascript component
@track searchString; @wire(searchContacts, { searchString: '$searchString' }) contacts;
When the searchString property is updated:
- The searchString's change causes the wired function to be re-evaluated.
- Therefore the value of 'contacts' changes.
- The component treats contacts as if it was tracked and causes the component to be re-rendered.
OK. That's pretty decent, and what the documentation says will happen. No surprises there!
But then I got to thinking: So, what happens if the property isn't tracked?
My first guess was that maybe the Apex method wouldn't get re-executed, but I wasn't entirely convinced - after all, the documentation only really makes a big deal about rendering. So I changed the code and tried again...
Javascript component
searchString; @wire(searchContacts, { searchString: '$searchString' }) contacts;
This time, when the searchString property is updated:
- The searchString's change causes the wired function to be re-evaluated.
- Therefore the value of 'contacts' changes.
- The component treats contacts as if it was tracked and causes the component to be re-rendered.
Erm. OK. It's the same. Hmmm....
Looking at what's actually going on, that does make sense. It's the '$searchString' reference that tells the framework that searchString is reactive, as respect to the wiring, so it's that causing the Apex to re-execute. And once the method is re-evaluated, the value of 'contacts' changes, and that causes the component to re-render.
That got me to thinking - so what does the '@track' do against the searchString in the original example. Experience tells me that these things generally will have an effect.
So I added something else to my example...
renderedCallback() { console.log( 'renderedCallback was called' ); }
This hooks into the component's lifecycle, as described here, and will tell us when the component gets re-rendered.
It turns out that my initial understanding of the first example was slightly wrong, though not in a way that would generally have much of an impact.
That is, if the parameter is tracked, you end up with the following:
- The searchString's change causes:
- The component to be re-rendered (since it is tracked).
- The wired function to be re-evaluated (since it is referenced as a '$' parameter).
- The execution of the wired function causes the value of 'contacts' to change.
- The component treats contacts as if it was tracked and causes the component to be re-rendered.
The result is that the component is re-rendered twice!
And sure enough, if you take the tracking off the searchString parameter, the component is only re-rendered once.
So, this does reinforce another point that the documentation makes here:
Personally, I think I'd call out this particular behaviour and remind people - you don't need to 'track' a property in order for the wired method to re-execute - but maybe it's just my lack of attention that missed that little point.
And I'd also state that you should only track a property that is being used as a reactive wired parameter if you need the property to be re-rendered before the Apex you are calling returns with its result.
No comments:
Post a Comment