Madhu
Madhu

Reputation: 2803

I am not able to use mapDispatchToProps in my React + Redux application

In my React + Redux application I am trying to use mapDispatchToProps utility, But whenever I put this inside connect(mapStateToProps, mapDispatchToProps) it gives me an error saying Uncaught TypeError: dispatch is not a function at new ReduxApp (ReduxApp.js:42)

What could be the issue in this? PS: below is the file

ReduxApp.js

 import React from 'react';
 import { Router, Route } from 'react-router-dom';
 import { connect } from 'react-redux';

 import { history } from './_helpers';
 import { alertActions } from './_actions'

 class ReduxApp extends React.Component {

  constructor(props) {
      super(props);

      this.handleChange = this.handleChange.bind(this);
      const { dispatch } = this.props;

      dispatch(alertActions.success("hello world"));
  }

  handleChange(){

      this.props.dispatch(alertActions.clear());
  }

  render(){
     const { alert } = this.props;
     return(

      <div>

         <h1>{alert.message}</h1>
         <button onClick={this.handleChange}>clear</button> {/* this is working since this function is declared outside the mapDispatchToProps. */}
         <button onClick={this.props.handleClick}>clear</button>

      </div>

     );

   }

 }

 const mapStateToProps = (state) => ({ 
   alert : state.alert
 });

 const mapDispatchToProps = (dispatch) => ({
   handleClick: () => dispatch(alertActions.clear())
 });

 const connectedApp = connect(mapStateToProps, mapDispatchToProps)(ReduxApp); // when I add mapDispatchToProps in the connect(), I get thhe issue.
 export { connectedApp as ReduxApp }

Upvotes: 1

Views: 615

Answers (2)

Madhu
Madhu

Reputation: 2803

From React Redux Official Documentation

Why don't I have this.props.dispatch available in my connected component?

The connect() function takes two primary arguments, both optional. The first, mapStateToProps, is a function you provide to pull data from the store when it changes, and pass those values as props to your component. The second, mapDispatchToProps, is a function you provide to make use of the store's dispatch function, usually by creating pre-bound versions of action creators that will automatically dispatch their actions as soon as they are called.

If you do not provide your own mapDispatchToProps function when calling connect(), React Redux will provide a default version, which simply returns the dispatch function as a prop. That means that if you do provide your own function, dispatch is not automatically provided. If you still want it available as a prop, you need to explicitly return it yourself in your mapDispatchToProps implementation.

The issue got solved after returning dispatch in the mapDispatchToProps implementation

 const mapDispatchToProps = (dispatch) => ({
         handleClick: () => dispatch(alertActions.clear()),
         dispatch, //returning dispatch solves the issue
 });

Note: If we use PropTypes no need to retun mapDispatchToProps

Upvotes: 2

t3__rry
t3__rry

Reputation: 2849

you first need to pass dispatch as it is not available when using mapDispatchToProps (see this answer by @gaeron Redux's creator: https://github.com/reduxjs/react-redux/issues/255)

const mapDispatchToProps = dispatch => ({
  handleClick: () => alertActions.clear(dispatch),
  dispatch,
});

Update your actionCreator to dispatch the action now that dispatch's reference is available:

alert.clear = dispatch => {
  // your logic
  dispatch(ALERT_CLEAR_ACTION) // or whatever you named your action
}

And in your component:

handleChange = () => this.props.handleClick();

Upvotes: 3

Related Questions