-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Avoid computing computed with storeToRefs()
#2812
Comments
This seems to be inherent to Vue's A possible improvement here would be to change the current implementation related to HMR in order to keep using the old version in Edit: I'm not completely sure we want to revert this change because if this behavior exists in current Vue, it's more natural to keep it. That being said I would like to have real world examples of why this change affects you |
storeToRefs()
I understand that this might be according to Vue's @posva as I'm not sure I understood your tips regarding avoiding computation correctly (and I can unfortunately also not view your "play" link as it throws an exception What exactly do you mean with "you can directly reference the store"? const { myComputedProp } = myStore instead of const { myComputedProp } = storeToRefs(myStore) ? Or what do you mean with your other mentioned fix "pass () => const myComputedProp = computed(() => myStore.myComputedProp) ? Thanks. |
I updated my comment with a fixed link. In your case, it seems like you can simply not use
Interested in learning more and available to help as well! |
I'd like to understand this more thoroughly. In the app I'm working on, we seem to use |
store.foo is reactive because store is a reactive object |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
I opened #2829 earlier but it was closed down, which is fine as I was still struggling with how to replicate the problem in the play link. I've spent 2 days debugging this issue in Pinia, and I finally understand what was happening in my project. One store was breaking my app, with a completely white screen and lots of Vue warn errors:
This specific store had some computed properties that were referencing other computed properties, like so:
In 2.2.4 and below, the above was perfectly fine. In 2.2.5 and above, my computed properties have to use optional chaining, otherwise the store breaks due to that early evaluation:
I also feel like the behaviour should not have been changed without warning. At the very least, docs should be updated to reflect the new behaviour. |
I just encountered someone having this problem on Vue Land. Here's a reproduction of the problem they were having: They were using This works fine with 2.2.4 and earlier, but fails with 2.2.5. As noted by others, this seems to have been caused by #2795. When function propertyToRef(
source: Record<string, any>,
key: string,
defaultValue?: unknown,
) {
const val = source[key]
return isRef(val)
? val
: (new ObjectRefImpl(source, key, defaultValue) as any)
} In Pinia 2.2.4 and earlier the With 2.2.5 the source object is now a proxy, so accessing Would the fix in Vue core be something like this? function propertyToRef(
source: Record<string, any>,
key: string,
defaultValue?: unknown,
) {
if (!isProxy(source)) {
const val = source[key]
if (isRef(val)) {
return val
}
}
return new ObjectRefImpl(source, key, defaultValue) as any
} If Update: The code I suggested above isn't quite right, as it won't handle |
@DaleMckeown In your case, the fix is very simple: |
@skirtles-code I marked this upstream but I think we could and should handle getters and computed differently in |
Good point, cheers for the hint. |
This causes some issues for me, as I throw an error on one getter in case some properties aren't yet set. Now most Let me know if you think this is an anti-pattern. |
Yes, that seems like an anti pattern: a computed shouldn’t throw |
I'm seeing the same issue with getters too. Now the getters seem to be evaluated as soon as I import the store, and that causes errors because of variables in the getters that are not yet initialized. |
@ezio-melotti I suppose you mean when using |
@posva, thanks for your reply and for looking into this! I understand that this change in behavior might have simply revealed already-existing errors in my code -- which is great! -- but it's nonetheless an unexpected change, especially for a bug-fix release. I'm also somewhat concerned about how the change might affect other computed/getters that are now evaluated earlier without failures, but might have side-effect that will cause issue later on. |
computed (and getters) should not have any side effects, that’s what watchers are for |
Reproduction
https://github.com/Ericlm/pinia-computed
Steps to reproduce the bug
Since version 2.2.5, computed values are evaluated at the start even if they're not displayed (when using storeToRefs).
It may be related to 254eec7
Expected behavior
The computed should only be evaluated when it is actually used.
Actual behavior
The computed is evaluated even if its value is displayed inside a
v-if="false"
.Additional information
No response
The text was updated successfully, but these errors were encountered: