Skip to content
This repository was archived by the owner on May 15, 2019. It is now read-only.
This repository was archived by the owner on May 15, 2019. It is now read-only.

backbone-mixin #19

Open
Open

Description

@lynnaloo

If the backbone-mixin is deprecated, then what are you using in it's place? I'm not sure if this is part of what was abandoned, but I'm wondering in the example why the Backbone model is a prop instead of in the state? Doesn't that force you to have to setProps on the parent and forceUpdate on the component?

Activity

  1. joelburget commented on Sep 22, 2014

    @joelburget
    Contributor

    The backbone mixin is deprecated for essentially the reason you mention - any change on the model causes a forceUpdate on the component.

    Internally we do have a version that uses state. It requires a bit more configuration because you have to tell it how to update state when the model changes, but I think that tradeoff is well worth it. I don't think it's gotten much use since we're gradually moving away from backbone backing our views to simple objects / flux.

    I'll leave this open until I add a note about this.

  2. gaearon commented on Oct 15, 2014

    @gaearon

    This is the mixin we used (until we transitioned to Flux as well):

    'use strict';
    
    var Backbone = require('backbone'),
        _ = require('underscore');
    
    var BackboneStateMixin = {
      getInitialState: function () {
        if (_.isFunction(this.getBackboneState)) {
          return this.getBackboneState(this.props);
        } else {
          return {};
        }
      },
    
      componentDidMount: function () {
        this._handleBackboneChange = _.throttle(this._handleBackboneChange, 16, {
          leading: true,
          trailing: true
        });
    
        if (!_.isFunction(this.watchBackboneProps)) {
          throw new Error('You must provide watchBackboneProps(props, listenTo).');
        }
    
        this._bindBackboneEvents(this.props);
      },
    
      componentWillReceiveProps: function (nextProps) {
        var haveBackbonePropsChanged = true;
    
        if (_.isFunction(this.haveBackbonePropsChanged)) {
          haveBackbonePropsChanged = this.haveBackbonePropsChanged(nextProps);
        }
    
        if (haveBackbonePropsChanged) {
          this._bindBackboneEvents(nextProps);
        }
      },
    
      componentWillUnmount: function () {
        this._unbindBackboneEvents();
      },
    
      _bindBackboneEvents: function (props) {
        this._unbindBackboneEvents();
    
        var listener = _.extend({}, Backbone.Events),
            listenTo = _.partial(listener.listenTo.bind(listener), _, _, this._queueHandleBackboneChange);
    
        this.watchBackboneProps(props, listenTo);
        this._backboneListener = listener;
      },
    
      _unbindBackboneEvents: function () {
        if (this._backboneListener) {
          this._backboneListener.stopListening();
          delete this._backboneListener;
        }
      },
    
      _queueHandleBackboneChange: function () {
        _.defer(this._handleBackboneChange);
      },
    
      _handleBackboneChange: function () {
        if (!this.isMounted()) {
          return;
        }
    
        if (_.isFunction(this.getBackboneState)) {
          this.setState(this.getBackboneState(this.props));
        } else {
          this.forceUpdate();
        }
      }
    };
    
    module.exports = BackboneStateMixin;

    Components define watchBackboneProps(props, listenTo), getBackboneState(props), optionally haveBackbonePropsChanged(nextProps).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions