Search code examples
meteorreactjsreduxredux-thunk

Thunks not dispatching


Can anyone see what's wrong with my thunks? The inner code is never called but the outer code is. This is an example thunk:

export function selectCustomer(customerId) {
    console.log("This appears in the console fine");
    return (dispatch, getState) => {
        console.log("This doesn't.. why don't you run..?");
        dispatch(loadCustomerToEdit(customerId));
    }
};

This is how I'm wiring it up to the component events:

import React, { Component, PropTypes } from 'react';
import CustomerEditForm from './CustomerEditForm.jsx';
import { editCustomer, selectCustomer, selectNewCustomer, saveCustomer } from '../redux/action_creators.jsx';


export const CustomerContainer = React.createClass({   
    componentWillMount() {
        const customerId = FlowRouter.getParam('_id');

        if (customerId) {
            this.sub = Meteor.subscribe('CustomerCompany.get', customerId, this.setCustomerInState);
        } else {
            this.props.selectNewCustomer();
        }
    },

    setCustomerInState() {
        console.log("setCustomerInState");
        this.props.selectCustomer(FlowRouter.getParam('_id'));
    },

    // Snip

    render() {
        console.log("CustomerContainer.render()", this.props);
        if (this.sub && !this.sub.ready) {
            return (<h1>Loading</h1>);
        }
        return (
            <CustomerEditForm
                customer = {this.props.customer}
                onChange = {this.props.onChange}
                onSave = {this.props.onSave}
                errors = {this.props.customer.errors}
                isValid = {this.props.customer.isValid}
                salesRegionOptions={SalesRegions.find().fetch()}
            />
        );
    }
});

CustomerContainer.propTypes = {
    customer: PropTypes.object,
    onSave: PropTypes.func.isRequired,
    onChange: PropTypes.func.isRequired,
    selectCustomer: PropTypes.func.isRequired,
    selectNewCustomer: PropTypes.func.isRequired   
};

function mapStateToProps(state) {
    console.log("CustomerContainer.mapStateToProps", state)
    return {
        customer: state.userInterface.customerBeingEdited
    };
}

function mapDispatchToProps(dispatch) {
    //console.log("CustomerContainer.mapDispatchToProps", Actions.customerSave)
    return {
        onSave: saveCustomer,
        onChange: editCustomer,
        selectCustomer,
        selectNewCustomer
    };
}

export default connect(mapStateToProps, mapDispatchToProps
)(CustomerContainer);

And this is my store setup:

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

const middleware = [ thunk ]

const createStoreWithMiddleware = applyMiddleware(...middleware)(createStore)
const store = createStoreWithMiddleware(rootReducer)

export default store;

You'll no doubt recognise a lot of this code as it is adapted from the excellent examples in the redux documentation.

The selectCustomer function is called, so mapDispatchToProps seems to have wired the selectCustomer function to the component, it's just that the method returned by selectCustomer isn't called.


Solution

  • The problem is your mapDispatchToProps function. react-redux does not automatically wrap your action creators if you pass it a function, only if you pass it an object! (or if you bind them manually with bindActionCreators)

    Try changing your connect call to this, and it should work:

    connect(mapStateToProps, {
      onSave: saveCustomer,
      onChange: editCustomer,
      selectCustomer,
      selectNewCustomer
    })(YourComponent);