Reputation: 2803
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
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
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