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
Error: Maximum recursive updates exceeded. You may have code that is mutating state in your component's render function or updated hook or watcher source function.
The error message is slightly misleading as the state mutation actually happens in a beforeUpdate hook. But to my mind that
isn't the real problem here.
In brief, perhaps I'm missing something but as far as I can tell:
The beforeMount and beforeUpdate hooks now run after render, not before.
There doesn't seem to be any way to react to changes in attrs within setup prior to the rendering update.
What is expected?
My own expectation would be for beforeMount and beforeUpdate to be called prior to render, as they were with Vue 2.
Failing that I can't see any way to react to attr changes in setup.
What is actually happening?
beforeUpdate is called too late to make the relevant state update.
Here's the reasoning behind the code:
The code is trying to partition attrs into two sets of attributes. One set is used on the root node and the other is used on an inner <input>.
I don't believe it's possible to use props to perform the partitioning because we can't have a prop for all data- attributes. The use of data- here is somewhat arbitrary, it could just as easily be prefixed listeners being sent to different child elements.
The code is using setup. If you don't use setup it is trivial to fix using computed properties and this.$attrs. The point here is trying to implement it with setup.
There doesn't seem to be any documented way to access the reactive property this.$attrs from within setup. It can be done with getCurrentInstance().proxy.$attrs but that isn't documented.
The attrs provided by the setup context object is not reactive.
It isn't possible to use attrs in a computed ref because it isn't reactive.
onBeforeUpdate seems like a natural place to sync the state based on attrs.
The problem is that onBeforeUpdate runs after render, which is too late. The attempt to update that state based on attrs gets in an infinite update loop.
I tried onRenderTriggered and onRenderTracked too but neither of them is called at the right time for this scenario.
There are ways to rewrite the code to defend against the loop, e.g. by checking whether the objects' properties have changed. Even then the component will render twice because onBeforeUpdate runs after the initial update rendering.
I'm unclear why beforeMount and beforeUpdate have been moved to be after render. I haven't been able to find an RFC explaining why this change has been made. My guess would be it was for consistency with directive hooks. Or maybe something to do with SSR? Either way they seem less useful running after render.
The text was updated successfully, but these errors were encountered:
Version
3.0.0-rc.5
Reproduction link
https://jsfiddle.net/skirtle/nr9j42mb/34/
Steps to reproduce
The error reads:
The error message is slightly misleading as the state mutation actually happens in a
beforeUpdate
hook. But to my mind thatisn't the real problem here.
In brief, perhaps I'm missing something but as far as I can tell:
beforeMount
andbeforeUpdate
hooks now run afterrender
, not before.attrs
withinsetup
prior to the rendering update.What is expected?
My own expectation would be for
beforeMount
andbeforeUpdate
to be called prior torender
, as they were with Vue 2.Failing that I can't see any way to react to
attr
changes insetup
.What is actually happening?
beforeUpdate
is called too late to make the relevant state update.Here's the reasoning behind the code:
attrs
into two sets of attributes. One set is used on the root node and the other is used on an inner<input>
.props
to perform the partitioning because we can't have a prop for alldata-
attributes. The use ofdata-
here is somewhat arbitrary, it could just as easily be prefixed listeners being sent to different child elements.setup
. If you don't usesetup
it is trivial to fix usingcomputed
properties andthis.$attrs
. The point here is trying to implement it withsetup
.this.$attrs
from withinsetup
. It can be done withgetCurrentInstance().proxy.$attrs
but that isn't documented.attrs
provided by thesetup
context object is not reactive.attrs
in acomputed
ref because it isn't reactive.onBeforeUpdate
seems like a natural place to sync the state based onattrs
.The problem is that
onBeforeUpdate
runs afterrender
, which is too late. The attempt to update that state based onattrs
gets in an infinite update loop.I tried
onRenderTriggered
andonRenderTracked
too but neither of them is called at the right time for this scenario.There are ways to rewrite the code to defend against the loop, e.g. by checking whether the objects' properties have changed. Even then the component will render twice because
onBeforeUpdate
runs after the initial update rendering.I'm unclear why
beforeMount
andbeforeUpdate
have been moved to be afterrender
. I haven't been able to find an RFC explaining why this change has been made. My guess would be it was for consistency with directive hooks. Or maybe something to do with SSR? Either way they seem less useful running afterrender
.The text was updated successfully, but these errors were encountered: