useState + watch + async fetch... should I just use Pinia at this point?

Hi All, New to Nuxt 3. I am using useState to hold my application state. I want to respond to a change in a state property (activeMembership) by doing a fetch (trpc/Prisma) and then using the fetch to update another bit of the state (notes). The following works ok but feels pretty clumsy.
// composables/states.ts
import { Membership, Note } from ".prisma/client"

export type AppState = {
activeMembership?: Membership
notes: Note[]
}

export const appState = () => useState<AppState>('appState', () => ({
notes: []
}));

// pages/dashboard.vue
const theAppState = appState();
watch(theAppState.value, (newAppState) => {
if(newAppState.activeMembership){
const { data: foundNotes } = $client.notes.getForCurrentUser.useQuery({account_id: newAppState.activeMembership.account_id});
if(foundNotes.value?.notes){
theAppState.value.notes = foundNotes.value.notes;
}
}
});
// composables/states.ts
import { Membership, Note } from ".prisma/client"

export type AppState = {
activeMembership?: Membership
notes: Note[]
}

export const appState = () => useState<AppState>('appState', () => ({
notes: []
}));

// pages/dashboard.vue
const theAppState = appState();
watch(theAppState.value, (newAppState) => {
if(newAppState.activeMembership){
const { data: foundNotes } = $client.notes.getForCurrentUser.useQuery({account_id: newAppState.activeMembership.account_id});
if(foundNotes.value?.notes){
theAppState.value.notes = foundNotes.value.notes;
}
}
});
Specifically, it feels strange to use a watch, it feels even stranger to put the watch + fetch in the setup script for the dashboard. I'm more familiar with Vuex where this would be an Action inside which I would dispatch a mutation to change the property (activeMembership) , then do the fetch, then dispatch another mutation to update the notes. No watches, central store, neat and tidy. Is there a neater way to utilise useState or do I just quit and move to Vuex/Pinia at this point?
2 Replies
Fabian B.
Fabian B.2y ago
Hey 🙂 I would first try to create multiple "useState" and not one giant app state. Will be better for performance since only the parts you need are loaded. Usestate is SSR friendly and therfore will be shipped and mounted server & client side. So Vuex is outdated, if you would like to use a more advanced state management option go for Pinia. I think for your case it makes sense. useState is great for simple requirements.
JavascriptMick
Thanks, I did end up using Pinia. Seems to be a nice solution for client heavy state management. this is what the action looks like
async changeActiveMembership(membership: Membership) {
if(membership !== this.activeMembership){
this.activeMembership = membership;
await this.fetchNotesForCurrentUser(); // another action
}
},
async changeActiveMembership(membership: Membership) {
if(membership !== this.activeMembership){
this.activeMembership = membership;
await this.fetchNotesForCurrentUser(); // another action
}
},
Want results from more Discord servers?
Add your server