Redux action no longer works when defining mapDispatchToProps As A Function

35 Views Asked by At

In a container, I've been using the "object shorthand" form of mapDispatchToProps to make available a single redux action (initialized as createRoutine from redux-actions) in an event handler:

const mapDispatchToProps = {
  validateAddress,
}

In the handler, the action appears in this form:

function () { return dispatch(actionCreator.apply(this, arguments));}

All good. But when instead I define mapDispatchToProps as a function, so that I can add other actions that need access to dispatch, like so...

const mapDispatchToProps = (dispatch) => {
  return {
      validateAddress: () => dispatch(validateAddress()),
      newAction1: .......,
      newAction2: .......,
  }
}

...my original action, validateAddress, ceases to work and appears now in this form instead:

function validateAddress() {
  return dispatch(Object(_core_address_module__WEBPACK_IMPORTED_MODULE_9__["validateAddress"])());
}

I'm not sure why this is happening or how to restore the functionality of my original action. Any ideas? Thanks.

1

There are 1 best solutions below

0
On

Your action creators such as validateAddress should return an object or a function that receives dispatch and getState functions for thunk actions.

Here is a working example:

const { Provider } = ReactRedux;
const { createStore, applyMiddleware, compose } = Redux;

const initialState = {
  validateAddress: 0,
};
//action types
const VALIDATE_ADDRESS = 'VALIDATE_ADDRESS';
//action creators
function validateAddress() {
  return { type: VALIDATE_ADDRESS };
}
const reducer = (state, { type }) => {
  if (type === VALIDATE_ADDRESS) {
    return {
      ...state,
      validateAddress: state.validateAddress + 1,
    };
  }
  return state;
};
//selectors
const selectValidateAddress = (state) =>
  state.validateAddress;
//creating store with redux dev tools
const composeEnhancers =
  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
  reducer,
  initialState,
  composeEnhancers(
    applyMiddleware(() => (next) => (action) =>
      next(action)
    )
  )
);
const App = ({ validateAddress, actionCalled }) => {
  return (
    <button onClick={validateAddress}>
      call action, called {actionCalled} times
    </button>
  );
};
const mapDispatchToProps = (dispatch) => {
  return {
    validateAddress: () => dispatch(validateAddress()),
  };
};
const mapStateToProps = (state) => ({
  actionCalled: selectValidateAddress(state),
});
const AppContainer = ReactRedux.connect(
  mapStateToProps,
  mapDispatchToProps
)(App);
ReactDOM.render(
  <Provider store={store}>
    <AppContainer />
  </Provider>,
  document.getElementById('root')
);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script>
<div id="root"></div>