Preventing problems accessing the current instance in a computed
#9974
Replies: 8 comments 12 replies
-
I like Idea 3. I have a project where some components suddenly stopped working because I upgraded to vue 3.4 and the UI library is relying on having access to If we set the Out of curiosity, what specific pitfalls do you see with relying on |
Beta Was this translation helpful? Give feedback.
-
I went with option (2) in 324e817, as the cases where it's used as a check now has |
Beta Was this translation helpful? Give feedback.
-
So, after updating to vue 3.4.6 from 3.3.9, I'm getting loads of warnings I traced it down to using pinia stores outside of vue components. Quick explanation, I have many classes that are dependent on some of our pinia stores. Inside a method in the class which requires the store, there's a call to the useStore for the required store. Everything works fine. I'm not calling getCurrentInstance anywhere but Pinia must be doing this internally since I get the warning on every call to one of my useStore in all of my classes. Any idea how I should/could fix this? Thanks! |
Beta Was this translation helpful? Give feedback.
-
Looks like Pinia calls |
Beta Was this translation helpful? Give feedback.
-
Since it is unclear whether OP managed to reproduce the vue-i18n issue, I'm posting a variant I was able to find fairly easily within my projects where 3.4.6 now displays a warning: https://stackblitz.com/edit/vitejs-vite-kdegwj?file=src%2Fmain.ts,src%2FApp.vue I'm not trying to imply that |
Beta Was this translation helpful? Give feedback.
-
I took a deeper look at the Pinia use cases (and also at the vue-i18n) case by @Ingramz , and I found that both are using I've reverted the warning for now in 2fd3905 before we figure out a safer way to warn users against actual wrong usage. |
Beta Was this translation helpful? Give feedback.
-
Also info if it may be of any help to all of you: we are using Nuxt, I18n, headless-ui and pinia in our project and all I can say is that although SSR somewhat passes with the way we are using the client side just dies on some interactions, to be more precise where we are using uI18n in pinia stores. Also headless-ui is spewing warnings like crazy. Seems to also be impacted |
Beta Was this translation helpful? Give feedback.
-
It seems that this not only happens with Pinia. I am not using Pinia in my Nuxt project, still get this warning: |
Beta Was this translation helpful? Give feedback.
-
There's a problem I've seen a few times on Vue Land with using
computed
and I'm wondering whether there's anything we can do in Vue core to mitigate it.The following code invokes a composable inside a
computed
callback:There's a potential problem with this code. A composable (typically) needs to be invoked during
setup
, rendering or a lifecycle hook. Acomputed
can't currently guarantee this, it would depend on when exactly the value is accessed.Here's a Playground example that shows the potential problem:
Both
c1
andc2
work fine, butc3
does not. It all comes down to whethergetCurrentInstance()
returns the relevant component at the moment the value is accessed.In my opinion, a
computed
shouldn't have a dependency ongetCurrentInstance()
. But this is an easy trap to fall into as the code appears to work in most cases.We saw an example like this on Vue Land yesterday where someone was calling
useI18n()
inside acomputed
. Their code worked in 3.3 but failed in 3.4. Sadly I don't have a reproduction, but it's easy to imagine that some small difference in the timing of the evaluation of thecomputed
could lead to this failing. From their perspective, this appears to be a regression in Vue.I think it's worth considering how we might try to help people avoid this pitfall.
Idea 1 - set current instance to
null
We could set the current instance to
null
when evaluating acomputed
. I suspect this would make a lot of people unhappy when their existing code blows up.Idea 2 - Have
getCurrentInstance()
log a warningWe could log a warning when trying to access
getCurrentInstance()
in acomputed
.This might not be as clean as it sounds because sometimes that function is called in cases where it doesn't necessarily matter what it returns (similar to
hasInjectionContext()
). For example, it might be called just to provide extra debug information during development, and we wouldn't want to log a warning in that case.Idea 3 - Set the current instance consistently
A
computed
created insidesetup
is already implicitly tied to the component via the dispose context. We could extend that link further by always setting the current instance to be the component before evaluating thecomputed
. For acomputed
created outside a component it could set the current instance tonull
.This is similar to idea 1, except that it'll lead to far fewer breakages. The downside is that it doesn't really do anything to discourage the dodgy code being written, it just ensures it'll behave consistently.
If this idea does end up being implemented, perhaps other effects (e.g.
watch
/watchEffect
) should work the same way?Idea 4 - Log a warning in
provide
/inject
/onMounted
This is similar to idea 2, but more targeted.
Rather than logging a warning for
getCurrentInstance()
calls, instead log a warning in the specific functions we care about, e.g.provide
/inject
/onMounted
/etc., if they are called during the execution of acomputed
callback. This is somewhat similar to the existing warnings that are logged when the current instance doesn't exist, but covering the case where it exists coincidentally.Beta Was this translation helpful? Give feedback.
All reactions