question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

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

See original GitHub issue

I am trying to resolve this issue. Am new to react.

Here is my offer action


import axios from 'axios';


// offers
export const FETCH_OFFERS = 'FETCH_OFFERS';
export const FETCH_OFFERS_SUCCESS = 'FETCH_OFFERS_SUCCESS';
export const FETCH_OFFERS_FAILURE = 'FETCH_OFFERS_FAILURE';
export const RESET_OFFERS = 'RESET_OFFERS';

// offer
export const FETCH_OFFER = 'FETCH_OFFER';
export const FETCH_OFFER_SUCCESS = 'FETCH_OFFER_SUCCESS';
export const FETCH_OFFER_FAILURE = 'FETCH_OFFER_FAILURE';
export const RESET_OFFER = 'RESET_OFFER';


const BASE_URL = location.href.indexOf('localhost') > 0 ? 'http://localhost:9001' : '';

export function fetchOffers(dispatch) {
	const request = axios({
		method: 'GET',
		url: `${BASE_URL}/offers`,
		headers: []
	});

	request.then((response) => {
		dispatch(fetchOffersSuccess(response));
	})
	.catch((err) => {
		dispatch(fetchOffersError(err))
	})

	return {
		type: FETCH_OFFERS,
		payload: request
	};
}

export function fetchOffersSuccess(offers) {
	return {
		type: FETCH_OFFERS_SUCCESS,
		payload: offers
	};
}

export function fetchOffersError(error) {
	return {
		type: FETCH_OFFERS_FAILURE,
		payload: error
	};
}

Root reducer

import { combineReducers } from 'redux';
import LoginReducer from '../components/login/LoginReducer';
// import HomeReducer from '../components/home/HomeReducer';
import OffersReducer from '../reducers/reducer_offers';
import event from './eventReducer';

export default combineReducers({
  currentUser: LoginReducer,
  offers: OffersReducer,
  event
});

store

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { composeWithDevTools } from 'redux-devtools-extension';
import rootReducer from './rootReducer';
import initialStore from './initialStore';

export default function configureStore() {

	
	return createStore(
	  rootReducer,
	  initialStore,
	  composeWithDevTools(
	    applyMiddleware(
	      thunk
	    )
	  )
	);
}

Reducers

import {
		FETCH_OFFERS, FETCH_OFFERS_SUCCESS, FETCH_OFFERS_FAILURE, RESET_OFFERS,
		FETCH_OFFER, FETCH_OFFER_SUCCESS, FETCH_OFFER_FAILURE, RESET_OFFER
	} from '../actions/offers';

	const INITIAL_STATE = { 
		offerList: {
			offers: [],
			error: null,
			loading: false
		},
		selectedOffer: {
			offer: null,
			error: null,
			loading: false
		}
	};

	export default function (state = INITIAL_STATE, action) {

		switch(action.type) {
			case FETCH_OFFERS:
				return {
					...state, offerList: {
						offers: [],
						error: null,
						loading: true
					}
				};
			case FETCH_OFFERS_SUCCESS:
				return {
					...state, offerList: {
						offers: action.payload,
						error: null,
						loading: false
					}
				};
			case FETCH_OFFERS_FAILURE:
				let error1 = action.payload || {message: action.payload.message}
				return {
					...state, offerList: {
						offers: [],
						error: error1,
						loading: false
					}
				};
			case RESET_OFFERS:
				return {
					...state, offerList: {
						offers: [],
						error: null,
						loading: false
					}
				};
			case FETCH_OFFER:
				return {
					...state, selectedOffer: {
						...state.selectedOffer,
						loading: true
					}
				};
			case FETCH_OFFER_SUCCESS:
				return {
					...state, selectedOffer: {
						offer: action.payload,
						error: null,
						loading: false
					}
				};
			case FETCH_OFFER_FAILURE: 
				let error2 = action.payload || {message: action.payload.message}
				return {
					...state, selectedOffer: {
						offer: null,
						error: error2,
						loading: false
					}
				};
			case RESET_OFFER:
				return {
					...state, selectedOffer: {
						offer: null,
						error: null,
						loading: false
					}
				};
			default: 
				return state;
		}
	}

error

I need help please

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:9 (1 by maintainers)

github_iconTop GitHub Comments

94reactions
dwaynecommented, Jul 21, 2017

Looking at

export function fetchOffers(dispatch) {
  const request = axios({
    method: 'GET',
    url: `${BASE_URL}/offers`,
    headers: []
  });
  
  request.then((response) => {
    dispatch(fetchOffersSuccess(response));
  })
  .catch((err) => {
    dispatch(fetchOffersError(err))
  })
  
  return {
    type: FETCH_OFFERS,
    payload: request
  };
}

I see you return the request promise in the action. A promise is not a plain object and so the returned action would not be a plain object and hence the error. Read here.

Since you’re using the thunk middleware your actions can be functions and here’s how you’d do it.

export function fetchOffers() {
  return function action(dispatch) {
    dispatch({ type: FETCH_OFFERS })

    const request = axios({
      method: 'GET',
      url: `${BASE_URL}/offers`,
      headers: []
    });
    
    return request.then(
      response => dispatch(fetchOffersSuccess(response)),
      err => dispatch(fetchOffersError(err))
    );
  }
}

To reiterate: fetchOffers is an action creator that returns a function as an action. This is only possible if you’re using the thunk middleware; which you are. Read here.

You may experience other errors after fixing this one so I’d recommend you continue this discussion on Stack Overflow.

43reactions
yaroslav0507commented, Apr 12, 2018

@prp-liza, Take a look at this example:

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

export default function configureStore() {  
  return createStore(
    rootReducer,
    applyMiddleware(thunk)
  );
}

Here we apply thunk middleware applyMiddleware(thunk).

This is what @apoorvtomar2222 means under Just Check redux-thunk import /applied is proper

Read more comments on GitHub >

github_iconTop Results From Across the Web

React-Redux: Actions must be plain objects. Use custom ...
This error occurs mainly if you are dispatching an action and your action is not returning an object. For example here ...
Read more >
Error: Actions must be plain objects. Use custom ... - YouTube
Error: Actions must be plain objects. Use custom middleware for async actions. 4K views 1 year ago. paradise _hope. paradise _hope.
Read more >
Async actions in bare Redux with Thunk or custom middleware
Learn how to manage asynchronous actions in React apps with Redux Toolkit, or a bare Redux implementation with custom middleware.
Read more >
error: actions must be plain objects. instead, the actual type was
Open side panel. How do I resolve "Actions must be plain objects. Use custom middleware for async actions.]"? Asked Apr 27, 2018 •...
Read more >
[Solved]-How to fix "Actions must be plain objects. Use custom ...
Coding example for the question How to fix "Actions must be plain objects. Use custom middleware for async actions."-Reactjs.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found