0

I am trying to set the user's current location in state using redux, but whenever I try I keep getting the error Actions must be plain objects. Use custom middleware for async actions. Everywhere I look it states this is an error of not having thunk, but as you can see from my store.js below I have applyMiddleware(thunk) in my store. Here are all of my files associated with this action:

store.js

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

const initialState = {};

const composeEnhancers = window._REDUX_DEVTOOLS_EXTENSION_COMPOSE_ || compose;

const store = createStore(
    rootReducer, 
    initialState,
    composeEnhancers(
        applyMiddleware(thunk),
        window.__REDUX_DEVTOOLS_EXTENSION__ ? window.__REDUX_DEVTOOLS_EXTENSION__() : f => f
      )
);

export default store;

locationAction.js

export const setLocationState = () => {
    dispatch => {
        navigator.geolocation.getCurrentPosition((position) => {
            dispatch({
                type: SET_LOCATION,
                payload: position
            });
        });
    }
}

Note: Even when I got rid of the dispatch and just had the setLocationState() function return type: SET_LOCATION I would get the same error, so that's leading me to believe that I may have configured something incorrectly somewhere.

locationReducer.js

const initialState = {
    latitude: 0,
    longitude: 0
}

export default (state = initialState, action) => {
    switch(action.type) {
        case SET_LOCATION:
            return {
                ...state,
                position: action.payload
            }

        default: 
            return state
    }
}

index.jsx

import { setLocationState } from '../../../actions/locationActions'

const locationState = useSelector(state => state.location);
const dispatch = useDispatch();
dispatch(setLocationState()) // <- Here is where error occurs
1

1 Answer 1

0

setLocationState looks buggy:

export const setLocationState = () => {
    dispatch => {
        navigator.geolocation.getCurrentPosition((position) => {
            dispatch({
                type: SET_LOCATION,
                payload: position
            });
        });
    }
}

Here, dispatch => {} is creating a new arrow function, but not returning that arrow function. So, setLocationState is actually going to end up returning undefined, which is not a valid action object.

The simple fix here should just be adding a return in front: return dispatch => {.

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

2 Comments

This in combination with changing dispatch(setLocationState()) to dispatch(setLocationState) solved my issue
dispatch(setLocationState) looks wrong, because setLocationState as seen in this example is a thunk action creator, which returns a thunk function that is what is actually passed to dispatch. I'd encourage you to read through redux.js.org/tutorials/fundamentals/part-6-async-logic and redux.js.org/tutorials/fundamentals/part-7-standard-patterns for explanations of how to do this correctly.

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.