apollo24
apollo24

Reputation: 313

(React/Redux) Async issue in a Redux action

Wasn't able to successfully use solutions from past posts.

I'm trying to run an action every time the app loads using useEffect on app.js like this :

  26 | const App = () => {
  27 |   
  28 |   useEffect(() => {
> 29 |     store.dispatch(loadUser());
  30 |   }, []);
  31 | 
  32 |   return (

The error i'm getting :

Error: Actions must be plain objects. Use custom middleware for async actions.

The action :

export const loadUser = () => (dispatch, getState) => {
      dispatch({ type: USER_LOADING})

      const token = getState().auth.token

      const config = {
          headers : {
              "Content-type": "application/json"
          }
      }

      if (token) {
          config.headers["x-auth=token"] = token
      }

      axios.get("/api/auth/user", config) 
      .then(res => dispatch({
          type: USER_LOADED,
          payload: res.data
      }))
      .catch(err => {
          dispatch(returnErrors(err.response.data, err.response.status))
          dispatch({
              type: AUTH_ERROR
          })
      })
  }

What am I doing wrong?

Upvotes: 0

Views: 147

Answers (3)

Spidy
Spidy

Reputation: 40002

Redux by itself is quite a simple workflow. Dispatched actions must be an object, usually with a type and a payload. This workflow is somewhat painful for async actions that require multiple dispatches through the phases of the action. That's where additional tools like Redux Thunk or Redux Sagas come in. It looks to me like you are using Redux Thunk but have not hooked the Thunk middleware up.

Wherever you are creating your store, you need to apply the redux thunk middleware like this.

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';

// Note: this API requires redux@>=3.1.0
const store = createStore(rootReducer, applyMiddleware(thunk));

Upvotes: 1

Jeff Astor
Jeff Astor

Reputation: 119

By default, actions in redux must return an object with a type key.

Your redux action creator is returning a function. This is a pattern most often used with the redux-thunk middleware. The redux-thunk middleware allows your actions to return a function that takes in the dispatch method to be called multiple times, if needed.

You'll want to install the redux-thunk package and include it in your middlewares array when you create your redux store.

Upvotes: 2

Muhammad Ali
Muhammad Ali

Reputation: 2648

When you have async logic in actions then you have to integrate some kind of middleware with redux, i.e. redux-thunk or redux-saga. I prefer thunk as it's more simpler to use.

Upvotes: 0

Related Questions