brigand/react-mixin

mixin this context is not bound to class scope?

Closed this issue · 8 comments

I'm getting this.shouldShowTooltip is undefined

module.exports = {
  showTooltip: function (event) {
    if (!this.shouldShowTooltip()) {
      return;
    }
  //...
}
class GraphNode extends Component {
  get displayName() {
    return 'TheGraphNode'
  }

  // ...
  shouldShowTooltip() {
    return (this.props.app.state.scale < TheGraph.zbpNormal);
  }

}

// Tried both, same error!?
// reactMixin(GraphNode.prototype, ToolTipMixin);
reactMixin.onClass(GraphNode, ToolTipMixin);

module.exports = GraphNode

What am I missing? Thanks

Perhaps an issue with autobinding (react-mixin doesn't autobind), but I'd need to see the rest of the code.

Add a componentWillMount that binds the methods.

componentWillMount: function() {
  this.showTooltip = this.showTooltip.bind(this);
}

Closing this because it's not actionable, but feel free to continue discussion.

Thanks, was not entirely clear to me from docs.

I would have thought that your mixin helper would do auto binding by default?

Just noticed: " If there are any more incompatibilites, other than autobinding methods which is intentionally omitted, please create an issue.'

So why is this not an option, such as autobind: true or autobind: [ list of props] ?

I ended up with this long winded approach. Would be nice if this kind of recipe was included IMO

// autobinder.js

function autobind(methodNames) {
  return {
    componentWillMount: function () {
      methodNames.forEach((name) => {
        prop = this[name]
        this[name] = prop.bind(this);
      });
    }
  };
}

function autobound(mixin) {
  return autobind(Object.keys(mixin))
}

module.exports = {
  autobind,
  autobound
}
var autobinder = require('../mixins/autobinder')
var ToolTipMixin = require('../mixins/tooltip')
const boundMixin = autobinder.autobound(ToolTipMixin)
reactMixin.onClass(GraphNode, ToolTipMixin);
reactMixin.onClass(GraphNode, boundMixin);

or even better, adding a new reactMixin.bindClass helper method to encapsulate this pattern

var ToolTipMixin = require('../mixins/tooltip')
var autobinder = require('../mixins/autobinder')

reactMixin.bindClass = function (clazz, mixin) {
  const boundMixin = autobinder.autobound(ToolTipMixin)
  reactMixin.onClass(clazz, mixin);
  reactMixin.onClass(clazz, boundMixin);
}

reactMixin.bindClass(GraphNode, ToolTipMixin)