-
-
Notifications
You must be signed in to change notification settings - Fork 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
Allow changing pinia root store for component scope #870
Comments
Probably a This is like nested pinias |
I notice the code below or |
I'm also looking for something like this, but for a different use-case. I want to explain here, and maybe get some opinions about it. TL;DR I don't want global state across all pages in the application, but "global state" on each page. We have a quite large application, with many pages (around 200), all of which are kind of "single page applications" themselves, with data, filters, side bars, popups etc. There is a big navigation menu, and when the user clicks on a different page in the menu, the expected behavior is that the destination page opens with a clean state. If they navigate back to the previous page, it's not expected to maintain the state that it had before (unless it's explicitly set up to do that via some persistence mechanism). Basically, it's supposed to work as if each menu click re-loads the page. However, we're using vue-router to navigate between the pages without re-loading, because it gives a much more responsive experience. We're not currently using any state management library, but just a combination of component state, and ad-hoc use of provide/inject on the different pages. I think it would be beneficial to have something like pinia, if we could make each page create a completely independent store, which is disposed when navigating away from the page. We could perhaps achieve this by calling I think something like |
A similar use case is having multiple, complex components in a single page (or nested components -> same app), whereas each component should handle its own pinia instance/store. |
+1 on this! I think this is a great feature. Simplifying complex nested components with a store is great for keeping things clean. But having the store be a global/singleton means that component is then a bit less reusable/isolated. Being able to 'scope' your stores to components means the components then are completely self contained/reusable and benefit from the cleaner architecture that using something like pinia provides 😄 Then you could have something neat like (complete pseudocode & probably not the best way to achieve). <script setup>
...
const props = {
myId: number
}
const piniaInstance = createPinia()
const componentStore = useComponentStore(piniaInstance)
componentStore.load(myId)
</script>
<template>
<sub-one :store="componentStore" />
<sub-two :store="componentStore" />
</template> Because currently you would have something like this in a sub component: <script setup>
...
const componentStore = useComponentStore()
</script>
<template>
... use the componentStore
</template> But now the sub component isn't self-documenting or that reusable... it assumes that the store has been loaded with the right data. How do we know what component is in charge of loading the store etc? You can't show two of the component with different data etc. |
When Now, i can't find a solution in pinia, so i write a tool to |
On this, rather than a pinia-side change; you could have an enforced version of the $reset workflow you're suggesting so that it couldn't be forgotten (I'm aware you're saying this feels unnatural, which is fair):
This automates the process you've described - although relies on you being aware that if you (for some reason) access a different page's store - that any changes made to that store won't be $reset but will be reset by accessing that different page. |
What problem is this solving
When documenting a component with storybook and its docs addon, multiple stories are rendered in one MDX document. That means they are technically part of the same Vue application.
Semantically however, each story represents a very specific state of the component. Usually these components would not access any global state (and thus pinia) at all, but sometimes it is necessary. That means each of the story components needs its own, independant “global” state.
Proposed solution
Pinia should allow to change the root store Pinia instance which is injected into a component and its descendents.
Technically this could be done simply by exposing the
piniaSymbol
and than I could useprovide(piniaSymbol, createPinia())
.On the other hand it might be more prudent to keep the symbol private and expose a convenience function
providePinia(pinia) { provide(piniaSymbol, pinia ?? createPinia()) }
.Describe alternatives you've considered
It is also possible to patch alias fields into the storybook webpack config and mock the store definition module which provides the
useMyStore
function for each store individually. Then each story could set a currentMock property in those modules.This would be much more complex however, harder to understand and possibly fragile.
The text was updated successfully, but these errors were encountered: