Home > Software design >  Pinia shared reactivity in stores
Pinia shared reactivity in stores

Time:01-17

Is it possible to share reactive state between stores in Pinia, for example:

export const useMainStore = defineStore('mainStore', {
state: () => ({
    data: [{name: "some name", amount: useSomeStore().amount}]
}),

export const useSomeStore = defineStore('someStore', {
state: () => ({
    amount: 0
}),

The idea is that useSomeStore.amount value is synced with the useMainStore data value.

So when I change the amount in useSomeStore to 5 I expect that data value in useMainStore will change accordingly to:

[{name: "some name", amount: 5}]

I know that I can subscribe to the store or use watchers but is there a better solution for this?

I made working solution using storeToRefs but not sure if there are drawbacks to this.

https://codesandbox.io/s/competent-breeze-wylkoj?file=/src/stores/tomato.ts

CodePudding user response:

Remember pinia states are reactive objects.

Therefore, you can always set a computed on one of them which references another store's state.

Generic example:

const useStoreOne = defineStore('one', {
  state: () => ({
    foo: 'bar'
  })
})

const useStoreTwo = defineStore('two', {
  state: () => ({
    foo: computed({
      get() { return useStoreOne().foo },
      set(val) { useStoreOne().foo = val } 
    })
  })
})

Note: storeToRefs does the same as above. So you can write storeTwo as:

const useStoreTwo = defineStore('two', {
  state: () => ({
    foo: storeToRefs(useStoreOne()).foo
  })
})

But it's kind of pointless. Why would you want to use useStoreTwo().foo anywhere instead of using useStoreOne().foo directly?

Make no mistake: the above pattern sets a two-way binding between the two store's foos. But, the second store's foo is useless. Anywhere you use it, you could be using the first one's foo directly.


On general principles, when you come across this pattern (or across the need for it), it should raise a flag: you're using state management because you want "one source of truth". Not more.

  • Related