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 foo
s. 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.