React Native - Actions must be plain objects
Tags: reactnative, redux, react, reduxthunk
Published: 2021-01-25 15:54:50

Hi everyone, I wrote this post because maybe someone could help me to understand what I missed in my code and my brain about this error:
"Error: Actions must be plain objects. Use custom middleware for async actions."

I found a lot of information about this error but I can't figure out the solution.

First of all, context:
I'm working with a react native app, I have redux and redux-thunk in my store, I need to do a async GET from a URL to obtain data and dispatch the action to my redux.

This is my store configuration with redux-thunk:

```
import {createStore, applyMiddleware,compose} from 'redux';
import Reducers from './reducers'
import thunk from 'redux-thunk'
import Reactotron from '../app/ReactotronConfig'

const middleware = applyMiddleware(thunk);
export default configureStore = () => {
    let store = createStore(Reducers,compose(middleware, Reactotron.createEnhancer()) );
    return store
}
```

This is my first dispatch in my main app module:

```
.
.
dispatch(statusActions.initialLoading());
```

In my actions I have this:

```
export const actionCreators = {

    initialLoading: () => async dispatch => {
        await authSetup();
        await dispatch(flowManagementActions.getEquipments());
    }

```

In my flowManagementActions I have this:

```
getEquipments: () => async dispatch => {
        const eqList = await dispatch(actionCreators.getEquipmentList());
        let prom = [];
        eqList.map( eq => {       prom.push(dispatch(actionCreators.getEquipmentsWithActivity(eq)));
        });
        return Promise.all(prom);
      },

getEquipmentsWithActivity: (eq) =>  async (dispatch, getState) => {

        return dispatch(FlowManagementService.fetchEquipments(eq).then(
          (response) => {
            data = {...response.data,"id":eq.id};
             return dispatch(
                {
                  type: 'GET_EQUIPMENTS',
                  target: 'equipments',
                  payload: {...data,"model":eq.model,"id":eq.id},
                }
              )
            }
          )
        );
        }
```

This is my FlowManagmentService

```
const testEndpoints = {
  fetchEquipments: (equipment) => 
  {
     return apiTest.get(`/equipments/${equipment.id}`)
  }
};

export default (testEndpoints);
```

apiTest use apiSauce

```
export const apiTest = create({
  baseURL,
  timeout: API_TIMEOUT
});
```
This is my reducer:

```
export default flowManagementReducer = (state = stateDescription, action) => {
    switch(action.type) {
        case "GET_EQUIPMENTS":
            {
              const newEquipments = state.equipments;
              newEquipments.push(action.payload);
              return {...state, equipments:newEquipments}
            }
        default:{
            return state
        }
        
    }
  }

  
```

The final result it's ok, I have in my store the data, but I get this error:

```
Error: Actions must be plain objects. Use custom middleware for async actions.
dispatch@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:100221:24
http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:134246:25
_callee2$@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:126398:59
tryCatch@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:24969:23
invoke@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:25142:32
tryCatch@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:24969:23
invoke@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:25042:30
http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:25072:19
tryCallTwo@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:27095:9
doResolve@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:27259:25
Promise@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:27118:14
callInvokeWithMethodAndArg@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:25071:33
enqueue@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:25076:157
async@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:25093:69
_callee2@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:126394:42
http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:126438:37
map@[native code]
_callee3$@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:126436:27
tryCatch@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:24969:23
invoke@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:25142:32
tryCatch@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:24969:23
invoke@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:25042:30
http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:25052:21
tryCallOne@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:27086:16
http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:27187:27
_callTimer@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:30626:17
_callImmediatesPass@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:30665:17
callImmediates@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:30882:33
__callImmediates@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:2736:35
http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:2522:34
__guard@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:2719:15
flushedQueue@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:2521:21
flushedQueue@[native code]
```

This are my dependecies in package.json

```
"dependencies": {
    "@react-native-async-storage/async-storage": "^1.13.2",
    "@react-native-community/masked-view": "^0.1.10",
    "@react-navigation/native": "^5.8.10",
    "@react-navigation/stack": "^5.12.8",
    "@reduxjs/toolkit": "^1.5.0",
    "apisauce": "^2.0.1",
    "react": "16.13.1",
    "react-native": "0.63.4",
    "react-native-config": "^1.4.1",
    "react-native-gesture-handler": "^1.9.0",
    "react-native-modal": "^11.6.1",
    "react-native-reanimated": "^1.13.2",
    "react-native-safe-area-context": "^3.1.9",
    "react-native-screens": "^2.16.1",
    "react-redux": "^7.2.2",
    "reactotron-apisauce": "^3.0.0",
    "reactotron-react-native": "^5.0.0",
    "reactotron-redux": "^3.1.3",
    "redux-logger": "^3.0.6",
    "redux-thunk": "^2.3.0",
    "reselect": "^4.0.0",
    "socket.io-client": "^3.0.5"
  }
```
Maybe someone give me a clue and I can continue work on that path

Thanks a lot, sincerely I'm worked on it for a lot of time but I can't found a explanation.


Thanks in advance for the orientation.

Sorry for my english if I had a mistake but I gave my best effort to write in the best way.