question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow changing pinia root store for component scope

See original GitHub issue

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 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:open
  • Created 2 years ago
  • Reactions:9
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

3reactions
ropezcommented, Jun 6, 2022

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 the Pinia instance provided a global reset function, that basically destroyed all registered stores, and we could hook that into the router, perhaps that would work.

2reactions
invokermaincommented, Sep 20, 2022

+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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Allow changing pinia root store for component scope #870
Proposed solution. Pinia should allow to change the root store Pinia instance which is injected into a component and its descendents.
Read more >
Using a store outside of a component - Pinia
The easiest way to ensure this is always applied is to defer calls of useStore() by placing them inside functions that will always...
Read more >
Complex Vue 3 state management made easy with Pinia
Let's first open main.js file to see how the Pinia root store is ... Now, open the App.vue file and replace its content...
Read more >
How to Migrate from Vuex to Pinia - Vue School Blog
Install Pinia and Modify Webpack Config ... The first step in migrating is installing the pinia npm package. ... I chose to leave...
Read more >
Quick Full Pinia Course. Vue VueX Pinia Store State Action…
In VueX, an action method cannot directly modify a state. ... The exposed root component instance allows us to view Pinia store instances....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found