Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Higher Order Component redux dispatch being overwritten by wrapped component redux dispatch

Below is the Higher order component. The HOC is connected to redux specifically to get access to one of the action creators: importantReduxAction.

function withExtraStuff (InnerComponent) {
  return class Enhancer extends React.Component {
    constructor(props){
      super(props)
      this.importantMethod = this.importantMethod.bind(this)
    }

    importantMethod(){
      //try to call the higher order component's action creator
      this.props.importantReduxAction()
    }

    render(){
      return <InnerComponent
        {...this.props}
        importantMethod={this.importantMethod}
      />
    }
  }

  let mapDispatchToProps = (dispatch)=>{
    return bindActionCreators({importantReduxAction}, dispatch)
  }
  return connect(null, mapDispatchToProps, null, {pure: false})(Enhancer)
}

This is the wrapped component that will use the HOC component. It also connects itself to redux in order to gain access to a different method: otherReduxAction.

class ChildComponent extends React.Component {
  constructor(props){
    super(props)
    this.doImportantThing = this.doImportantThing.bind(this)
  }

  doImportantThing(){
    //try to call the higher order component's method (this is where problems occur)
    this.props.importantMethod()

    //do something with this components dispatch
    this.props.otherReduxAction()
  }

  render(){
    return <div>
      {this.doImportantThing()}
    </div> 
  }
}

let EnhancedComponent = withExtraStuff(ChildComponent)

let mapDispatchToProps = (dispatch)=>{
  return bindActionCreators({otherReduxAction}, dispatch)
}

export default connect(null, mapDispatchToProps, null, {pure: false})(EnhancedComponent)

The problem occurs that my mapDispatchToProps inside of my HOC is being overwritten by the child, and the action creator: importantReduxAction, is never being passed into my HOC. It receives the error that the:

method is undefined

I have solved this by passing the method into my child component like so:

/* CHILD COMPONENT DEFINITION ABOVE */

let mapDispatchToProps = (dispatch)=>{
  return bindActionCreators({otherReduxAction, importantReduxAction}, dispatch)
}

But that solution is not really the way that I want things to work. Is there a way to have my HOC merge in the action creators that it wants to use with those of the wrapped component? Or am I going to have to find a new way around this?

TLDR: HOC Component that uses an action creator wraps child component that also has one. HOC action creator gets kicked to curb and never passed.

like image 395
James Kirkpatrick Avatar asked Aug 18 '17 16:08

James Kirkpatrick


1 Answers

It looks like you have an issue with your example.

function withExtraStuff (InnerComponent) {
  return class Enhancer extends React.Component {/* ... */}

  // ...

  return connect(/* ... */)(Enhancer)
}

You're returning twice from your HOC, so your Enhancer is never connected.

Is this just a typo in your example? Or do you have this same issue in your code? Because that would indeed cause the issue you're seeing.

like image 187
Luke Willis Avatar answered Sep 18 '22 11:09

Luke Willis