Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

This.props.dispatch not a function - React-Redux

I am trying to dispatch an action from within my smart component. I've tried to use the mapDispatchToProps and this.props.dispatch(actions.getApplications(1)) but neither is binding the actions to props.

Im not sure if it is because my mapStateToProps is not included? I tried to include it but it did not work either.

Any help is appreciated, I apologize for the length of the code block below.

import classNames from 'classnames'; import SidebarMixin from 'global/jsx/sidebar_component';  import Header from 'common/header'; import Sidebar from 'common/sidebar'; import Footer from 'common/footer'; import AppCard from 'routes/components/appCard'; import { getApplications } from 'redux/actions/appActions';  import { connect } from 'react-redux' import { bindActionCreators } from 'redux'  import actions from 'redux/actions'; import { VisibilityFilters } from 'redux/actions/actionTypes';   class ApplicationContainer extends React.Component {     constructor(props){     super(props)      this.state = {       applicants: []     }      this.onDbLoad = this.onDbLoad.bind(this)    }   onDbLoad(){     console.log(this.props.dispatch)      // this.props.getApplications(1)   }      render() {     return (         <Col sm={12} md={4} lg={4}>             <PanelContainer style={panelStyle}>                 <Panel>                     <PanelBody >                         <Grid>                             <Row>                               { this.onDbLoad() }                             </Row>                       </Grid>                     </PanelBody>                 </Panel>             </PanelContainer>         </Col>     )} }   function mapDispatchToProps(dispatch){    return bindActionCreators({ getApplications: getApplications },dispatch) }  export default connect(null, mapDispatchToProps)(ApplicationContainer);  @SidebarMixin export default class extends React.Component {      render() {     const app = ['Some text', 'More Text', 'Even More Text'];          var classes = classNames({             'container-open': this.props.open         })         return (             <Container id='container' className={classes}>                 <Sidebar />                 <Header />         <Container id='body'>           <Grid>             <Row>               <ApplicationContainer />             </Row>           </Grid>         </Container>                 <Footer />             </Container>     )} } 
like image 360
richTheCreator Avatar asked Apr 25 '16 21:04

richTheCreator


People also ask

What is this props dispatch?

props. dispatch() is a more logical and better approach to dispatching actions in Redux than using store. dispatch() directly, as it makes sure that your Redux store does not become a singleton module. Most of the time, dispatch() is called from within the store consuming components and, similar to this.

What is bindActionCreators in Redux?

bindActionCreators(actionCreators, dispatch) Turns an object whose values are action creators, into an object with the same keys, but with every action creator wrapped into a dispatch call so they may be invoked directly. Normally you should just call dispatch directly on your Store instance.

What is mapStateToProps?

As the first argument passed in to connect , mapStateToProps is used for selecting the part of the data from the store that the connected component needs. It's frequently referred to as just mapState for short. It is called every time the store state changes.


2 Answers

Per the Redux FAQ question at here, this.props.dispatch is available by default if you do not supply your own mapDispatchToProps function. If you do supply a mapDispatchToProps function, you are responsible for returning a prop named dispatch yourself:

const mapDispatchToProps = dispatch => ({    ...other methods,    dispatch                // ← Add this })  export default connect(null, mapDispatchToProps)(Component) 

Or, you can make sure your action creators are pre-bound using Redux's bindActionCreators utility, and skip having to worry about using this.props.dispatch in your component.

like image 124
markerikson Avatar answered Sep 18 '22 13:09

markerikson


As you mentioned in your question, mapDispatchToProps should be the second argument to connect.

If you don't have any state mapping to be done, you can pass null as the first argument:

export default connect(null, mapDispatchToProps)(ApplicationContainer); 

After you do this, then this.props.getApplications will be bound.


As per your comment, if you want to have access to this.props.dispatch INSTEAD of binding actions, simply call connect() without passing any mappers, and the default behavior will inject dispatch.

If you want to have BOTH bound action creators and this.props.dispatch, you need to add a dispatch to the object that you pass to mapDispatchToProps as well. Something like dispatch: action => action. Or, since you're not putting everything under a root key (like actions), you could do:

function mapDispatchToProps(dispatch) {   let actions = bindActionCreators({ getApplications });   return { ...actions, dispatch }; } 
like image 31
Interrobang Avatar answered Sep 18 '22 13:09

Interrobang