Skip to content

Instantly share code, notes, and snippets.

@lourd
Created March 5, 2015 18:50
Show Gist options
  • Save lourd/a7f978e278d1274babe9 to your computer and use it in GitHub Desktop.
Save lourd/a7f978e278d1274babe9 to your computer and use it in GitHub Desktop.
Tracker Mixin for React
/**
* React Mixin for binding reactive data sources and DDP subscriptions
* to the state of a component using Tracker
*
* Components using this mixin should implement getTrackerState and/or
* ddpSubscriptions
*/
TrackerMixin = {
getInitialState: function() {
if ( self.ddpSubscriptions ) {
return {
subsReady: false
};
}
return {};
},
componentWillMount: function() {
var self = this;
// self._trackerDep = new Tracker.Dependency();
if ( Meteor.isClient ) {
Tracker.autorun( function(computation) {
self._trackerComputation = computation;
// self._trackerDep.depend();
if ( self.ddpSubscriptions ) {
// By setting up subscriptions in a Tracker.autorun they will
// automatically be canceled when the computation stops
// console.log("TrackerMixin rerunning DDP subscriptions");
var handles = self.ddpSubscriptions();
var ready;
if (_.isArray(handles)) {
// if it's an array of handles, wait on all of them
// to be ready
ready = _.reduce(
handles,
function(result, handle) {
return result && handle.ready();
},
true
);
} else {
ready = handles.ready();
}
self.setState({ subsReady: ready });
}
if ( self.getTrackerState ) {
self.setState( self.getTrackerState() );
}
});
} else { // we're on the server
if ( self.getTrackerState ) {
self.setState( self.getTrackerState() );
}
}
},
// This is here in case getTrackerState relies on any prop values
// If you're doing reactivity based on props, you're doing it wrong
// componentWillReceiveProps: function(nextProps) {
// if (this._trackerDep) {
// var oldProps = this.props;
// this.props = nextProps; // setup props for the autorun
// this._trackerDep.changed(); // trigger the autorun
// Tracker.flush(); // make sure the autorun goes
// // XX this was giving a bug when no props were being used
// // "can't call tracker.flush while flushing"
// this.props = oldProps; // setup props back to what they were
// // React will handle actually setting them
// }
// },
componentWillUnmount: function() {
if ( this._trackerComputation ) {
this._trackerComputation.stop();
this._trackerComputation = null;
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment