Nuxtstop

For all things nuxt.js

Pinia: How to reset stores created with function/setup syntax

19 0

What is Pinia

Pinia is a state management solution for Vue 3.
If you are thinking "Oh, another tool?", the truth is that Pinia can be thought as the next version of Vuex 4. Or as Evan said:

Pinia shares a lot of similarities with Vuex but it's simpler, type safe and extensible!

If you haven't tried it yet, checkout the docs to get started!

Object and Function stores

There are two ways of creating a store with Pinia.

Object syntax:

import { defineStore } from 'pinia'

export const useStore = defineStore('main', {
  state: () => ({
    counter: 0,
  }),
  getters: {
    doubleCount: (state) => state.counter * 2,
  },
  actions: {
    increment() {
      this.counter++
    },
  }
})
Enter fullscreen mode Exit fullscreen mode

Function syntax:

import { ref, computed } from 'vue'
import { defineStore } from 'pinia'

export const useStore = defineStore('main', () => {
  const counter = ref(0)
  const doubleCounter = computed(() => counter.value * 2)

  function increment() {
    counter.value++
  }

  return {
   counter,
   doubleCounter,
   increment
  }
})
Enter fullscreen mode Exit fullscreen mode

The Object syntax looks very similar to Vuex. The Function syntax is similar to a component setup() method where we manually define reactivity.

How to reset the store with Object syntax

When using Object syntax you can simply call the built-in $reset method:

<script setup>
import { useStore } from './useStore'

const store = useStore()

store.$reset // πŸ‘ˆ

</script>
Enter fullscreen mode Exit fullscreen mode

However, with Function syntax the built-in $reset method simply throws an error:

🍍: Store "main" is build using the setup syntax and does not implement $reset().
Enter fullscreen mode Exit fullscreen mode

How to reset the store with Function syntax

In order to make $reset method work with Function syntax we are going to create a Pinia plugin: ✨

reset-store.js

import cloneDeep from 'lodash.clonedeep'

export default function resetStore({ store }) {
  const initialState = cloneDeep(store.$state)
  store.$reset = () => store.$patch(cloneDeep(initialState))
}
Enter fullscreen mode Exit fullscreen mode

Here, we deep-copy the initial state of the store with lodash.clonedeep and we add the $reset function which sets the state to its initial value. It's important to deep-copy the state again in order to remove references to the copy itself.

With store.$patch we apply multiple changes at the same time. Read more on the docs.

Then in main.js or wherever you initialize Pinia:

// ...
import { resetStore } from './reset-store'

//...
const pinia = createPinia()
pinia.use(resetStore)

app.use(pinia)

//...
Enter fullscreen mode Exit fullscreen mode

See demo here on Stackblitz or embed:

Learn more about Pinia plugins

Conclusion

Awesome! Now no matter if we use Object or Function syntax, $reset method works! πŸ₯³πŸ₯³

I want to thank on of the best Vue devs out there @tony19 for his answer on StackOverflow.