0

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?

3
  • Your loadUser returns a function, not an object. Seems like you havent configured redux-thunk properly Commented Mar 22, 2020 at 19:36
  • dispatch(returnErrors(err.response.data, err.response.status)) Is returnErrors an action? Commented Mar 22, 2020 at 19:42
  • Yes it comes from an errorActions file Commented Mar 22, 2020 at 19:56

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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));

1 Comment

Can you put the code up on CodeSandbox.io or something? Or add the code for returnErrors? Do you have a redux logger running to see which action its failing after so we can narrow down the specific instance?
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.