You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I know that custom equality for watch has been brought up few times in the past and the general consensus is that it should just be done inside watch callback. But if one wants to use onCleanup, this approach does not work well: onCleanup of previous run is called even if custom equality determines that nothing should be done.
I have the following use case, where I want to reactivity fetch data from the server if and only if fetch URL changes (slightly abridged):
constdoc=ref<DocType|null>(null)watch([()=>props.params,()=>props.name,()=>props.query],async([params,name,query],[oldParams,oldName,oldQuery],onCleanup)=>{// Do nothing if nothing changed.if(isEqual(params,oldParams)&&isEqual(name,oldName)&&isEqual(query,oldQuery)){return}constabortController=newAbortController()onCleanup(()=>abortController.abort())constnewURL=router.resolve({
name,
params,
query,}).hreftry{constresponse=awaitgetURL(newURL,abortController.signal)if(abortController.signal.aborted){return}doc.value=response.doc}catch(error){if(abortController.signal.aborted){return}console.error(error)return}},{immediate: true,deep: true,},)
The issue is that params and query are objects and even if their contents do not change really, but they are just recreated (e.g., inside a template with something like :query="{id: value}"), the watch triggers. Fine, I do deep comparison with isEqual but the issue is that onCleanup aborts the previous request even if isEqual determines that nothing has changed and nothing should be done (so existing in-flight non-aborted-yet fetch should continue to run and finish and update doc ref).
Now, there are few approaches I could take, like doing JSON.stringify on query and params to get a simple string as a reactive value so that existing strict equality would work correctly.
Or I could move abortController to external-to-the-watch variable and be smart to call it only if params change. But then I also have to call it when any outside scope gets destroyed and I have to keep track of that.
I think the easiest and cleanest and more readable would be if I could provide my own equality function. Something like:
{
immediate: true,
deep: true,
equals: isEqual
},
Then it would be easy and clear to anyone reading the code, what is the idea here.
The text was updated successfully, but these errors were encountered:
I could claim that deep: true should already do that, making callback rerun only if any of deeply nested values really changes and is not just recreated, but I think I read in some other issues that this will not happen, and is probably backwards incompatible at this point anyway.
I know that custom equality for watch has been brought up few times in the past and the general consensus is that it should just be done inside watch callback. But if one wants to use
onCleanup
, this approach does not work well:onCleanup
of previous run is called even if custom equality determines that nothing should be done.I have the following use case, where I want to reactivity fetch data from the server if and only if fetch URL changes (slightly abridged):
The issue is that
params
andquery
are objects and even if their contents do not change really, but they are just recreated (e.g., inside a template with something like:query="{id: value}"
), the watch triggers. Fine, I do deep comparison withisEqual
but the issue is thatonCleanup
aborts the previous request even ifisEqual
determines that nothing has changed and nothing should be done (so existing in-flight non-aborted-yet fetch should continue to run and finish and update doc ref).Now, there are few approaches I could take, like doing
JSON.stringify
on query and params to get a simple string as a reactive value so that existing strict equality would work correctly.Or I could move
abortController
to external-to-the-watch variable and be smart to call it only if params change. But then I also have to call it when any outside scope gets destroyed and I have to keep track of that.I think the easiest and cleanest and more readable would be if I could provide my own equality function. Something like:
Then it would be easy and clear to anyone reading the code, what is the idea here.
The text was updated successfully, but these errors were encountered: