Use actions for asynchronous data operations, for example REST API calls.

The context argument is an object with two keys - mutations and actions. You can use it to dispatch another action that's dependent on your current action's data and to alter the current state.

const store = {
  state: {
    user: null,
    posts: []
  },
  mutations: {
    USER_SET (state, data) {
      state.user = data
    }
    POSTS_SET (state, data) {
      state.posts = data
    }
  },
  actions: {
    async USER_POSTS_FETCH (context, userId) {
      const data = await userPostsCall(userId)
      context.mutations.POSTS_SET(data)
    }
    async USER_FETCH (context) {
      // fetch the current user
      const user = await userApiCall()
      context.mutations.USER_SET(user)
      
      // find out their ID and based on that dispatch an action to fetch their posts
      context.actions.USER_POSTS_FETCH(user.id)
    }
  }
}

useAction

useAction<T>(actionName: string) => (args?: any) => Promise<T>

To use an action in a component, use the useAction() hook. Actions always return a promise. They don't get re-created, so you're safe with using them as dependencies for useEffect or useCallback.

import { useEffect } from 'react'
import { useAction, useGetter } from 'vuex-but-for-react'

const UserComponent = () => {
  const onUserFetch = useAction('USER_FETCH');
  
  useEffect(() => {
    onUserFetch();
  }, [onUserFetch])
  
  const user = useGetter('user');
  
  return (
    ...
  )
}

useActions

useActions(values: string[]) => ((args?: any) => Promise<any>)[]

If you wish to use more actions in a component, you can use the useActions() hook instead of using useAction() multiple times. The returned functions will be in the same order as provided arguments.

const [handleUserFetch, handlePostsFetch] = useActions(['USER_FETCH', 'USER_POSTS_FETCH']);

useActionOnMount

useActionOnMount<T>(actionName: string, ...params: any[]) => void;

The hook useActionOnMount() was created for user's convenience, where the action will execute on component mount only, unless the provided parameters change. Each parameter change will trigger a re-fetch. This saves the user the need to write useEffect code and serves as a wrapper for it.

import { useActionOnMount, useGetter } from 'vuex-but-for-react'

const UserComponent = () => {
  useActionOnMount('USER_FETCH');
  const user = useGetter('user');
  
  return (
    ...
  )
}

useAction with modules

To access a module's action, use the module name as the prefix.
const action = useAction('counter/COUNTER_FETCH')

const store = {
  state: {
    ...
  },
  mutations: {
    ...
  },
  modules: {
    counter: {
      state: { count: 0 },
      mutations: {
        COUNTER_SET (state, newValue) {
          state.count = newValue
        }
      },
      actions: {
        async COUNTER_FETCH (context) {
          const data = await dummyApiCall()
          // a module does not have access to the parent actions and mutations
          context.mutations.COUNTER_SET(data)
        }
      }
    }
  }
}