Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redux-thunk async actions: Use custom middleware for async actions

I am using redux-thunk for async actions and babel-polyfill for promises. I get the following error: Error: Actions must be plain objects. Use custom middleware for async actions.

I solved this problem by including redux-promise in my middleware. I am not sure why I had to use redux-promise to resolve this issue because all examples in Redux docs use babel-polyfill. Should I continue using redux-promise or I might have some issues with babel-polyfill?

babel-polyfill is included in my app entry point:

import 'babel-polyfill';

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';

import App from './components/App.jsx';
import store from './store.jsx';

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>
    , document.querySelector('.container'));

UPDATE:

So I checked just in case if I have redux-thunk installed. It is in my package.json. Here is my store.js

import thunkMiddleware from 'redux-thunk';
import promise from 'redux-promise'

export default store = createStore(
  rootReducer,
  defaultState,
  applyMiddleware(
    thunkMiddleware,
    promise
  )
);

Here is my async action in action.js:

function receiveStates(json) {
    return {
        type: RECEIVE_STATES,
        states: json.states,
    };
}

export function fetchStates(uuid) {
    return dispatch =>
        fetch(`https://my-api.com/session/${uuid}`)
        .then(response => response.json())
        .then(json => dispatch(receiveStates(json)));
}

Here is how I call action from component:

fetchStates(sessionID) {
    this.props.dispatch(fetchStates(sessionID));
}
# I bind this function in component's constructor 
this.fetchStates = this.fetchStates.bind(this);

And finally, this is my reducer:

function statesReducer(state = null, action) {
    switch (action.type) {
        case RECEIVE_STATES:
            return { ...state, states: action.states };
        default:
            return state;
    }
}
like image 309
dzeno Avatar asked Aug 13 '16 08:08

dzeno


People also ask

How do you handle async actions in Redux?

Redux Async Data Flow​ Just like with a normal action, we first need to handle a user event in the application, such as a click on a button. Then, we call dispatch() , and pass in something, whether it be a plain action object, a function, or some other value that a middleware can look for.

Is Redux thunk a middleware?

Redux Thunk middleware allows you to write action creators that return a function instead of an action. The thunk can be used to delay the dispatch of an action, or to dispatch only if a certain condition is met. The inner function receives the store methods dispatch and getState as parameters.

Why do we use Redux thunk middleware?

It allows us to return functions instead of objects from redux actions. Plain redux doesn't allow complex logic inside action functions, you can only perform simple synchronous updates by dispatching actions. This middleware extends its ability and lets you write complex logic that interacts with the store.

Can actions be async?

As a result, actions that complete quickly usually run synchronously. For example, action=getstatus is a synchronous action. Actions that can take a significant time to complete are usually asynchronous.


1 Answers

I think your error could be caused by:

  1. You are not returning a thunk (a function returning a function of dispatch) from your action creator, so that the Thunk middleware doesn't catch it (maybe you are returning a promise instead?)
  2. You have not installed redux-thunk as suggested by dzeno

I suggest that you install the redux-logger middleware and add it to your store middlewares as the last one, removing the promise middleware which you would not need if returning a thunk. In this way all the actions are logged in console (previous state, current action, next state) and you can debug what action object type you are returning that is not "digested" by the thunk middleware.

like image 76
Matteo Frana Avatar answered Sep 22 '22 23:09

Matteo Frana