Allow changing pinia root store for component scope
See original GitHub issueWhat 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 use provide(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.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:9
- Comments:5 (1 by maintainers)
Top GitHub Comments
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
$reset
when opening a page, but it doesn’t feel natural. We would easily forget to do it, and create unwanted behavior that would be missed by QA. Also, it seems wasteful to have a big store holding state from all previously visited pages, that we don’t need.I think something like
providePinia
, would be perfect for our use-case. Alternatively, if thePinia
instance provided a global reset function, that basically destroyed all registered stores, and we could hook that into the router, perhaps that would work.+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).
Because currently you would have something like this in a sub component:
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.