Search code examples
javascriptreactjsreduxaxiosredux-thunk

Uncaught Error: Actions must be plain objects


I have poured through all the questions with this title and I cannot find a solution that prevents this error. What I've tried so far is to ensure I'm not confusing old and new redux api, I'm transpiling using babel so no typescript solutions apply, I've ensured I'm returning a function in the action in question, I've commented out my import or thunk to make sure it breaks and I've logged out thunk after importing it and I get a function back, and I've updated the devtools extension from the depricated version. No success. Any help is MUCH appreciated. Relevant code follows:

Store:

const redux = require('redux');
const {combineReducers, createStore, compose, applyMiddleware} = require('redux');
import {default as thunk} from 'redux-thunk';

const {nameReducer, hobbyReducer, movieReducer, mapReducer} = require('./../reducers/index');

export const configure = () => {

    const reducer = combineReducers({
        name: nameReducer,
        hobbies: hobbyReducer,
        movies: movieReducer,
        map: mapReducer
    });

    const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

    const store = createStore(reducer, composeEnhancers(applyMiddleware(thunk)));   

    return store;
};

Actions:

export let startLocationFetch = () => {type: 'START_LOCATION_FETCH'};

export let completeLocationFetch = (url) => {type: 'COMPLETE_LOCATION_FETCH', url};

export let fetchLocation = () => (dispatch, getState) => {
    dispatch(startLocationFetch());

    axios.get('http://ipinfo.io').then(function(res) {
        let loc = res.data.loc;
        let baseURL = 'http://maps.google.com?q=';

        dispatch(completeLocationFetch(baseURL + loc));
    });
};

Code where action is dispatched:

console.log('starting redux example');

const actions = require('./actions/index');
const store = require('./store/configureStore').configure();

let unsubscribe = store.subscribe(() => {
    let state = store.getState();

    if(state.map.isFetching){
        document.getElementById('app').innerHTML = 'Loading...';
    } else if(state.map.url){
        document.getElementById('app').innerHTML = '<a target=_blank href = "' + state.map.url + '">Location</a>';
    }
});



store.dispatch(actions.fetchLocation());

I am just learning React/Redux now (this is for a course) so I really maybe missing something obvious. If I've left out something pertinent, let me know. Thanks


Solution

  • export let startLocationFetch = () => {type: 'START_LOCATION_FETCH'};
    

    is not returning an object, but should rather result in a syntax error.

    To directly return an object from an arrow function, you need to set brackets, or it will be interpreted as a block:

    export let startLocationFetch = () => ({type: 'START_LOCATION_FETCH'});
    

    Edit: Thanks to Nicholas for pointing out that is indeed not a syntax error.