React & fine-grained/external reactivity

So I’m slowly converting over my code to React and I’ve been finding it all pretty easy going, until now.

I have a “Subscription Management” component which is my “smart” component, that gets all the data for the stateless/“dumb” components that it renders. This is the first time that I have a component that gets data from outside mongodb, as the subscription itself is stored in Stripe.

As you can see below I’ve created a state field to hold the subscription and I get the value on first load, but it needs to also update if the data.site.stripeSubscriptionId value is changed or is removed. (This happens via a webhook from Stripe, all server-side)

This is where I get a little stuck; a) I can’t figure out how to get the level of fine-grained reactivity that will only run code when data.site changes, rather than any reactive source (ie. state) b) I can’t change state values in getMeteorData() for that very reason as it will likely cause an infinite loop!

So how do I fire off a Meteor.call('Stripe.getSubscription'); every time the data.site.stripeSubscriptionId is changed?

SubscriptionManagement = React.createClass({
  mixins: [ReactMeteorData],
  getInitialState() {
    return {
      subscription: null
    };
  },
  getMeteorData() {
    const data = {};

    data.user          = Meteor.user();
    data.isSiteAdmin = Roles.userIsInRole(data.user, 'site_admin');

    const userSite = !!data.user ? data.user.profile.site : '';
    data.site = Sites.findOne({ _id: userSite });

    // If the site.stripeSubscriptionId ever changes we need to update the Subscription.... HOW?
    // especially as a setState call isn't allowed inside the getMeteorData() function!

    return data;
  },
  componentWillMount() {
    // Go and attempt to get the details of the current subscription
    Meteor.call('Stripe.getSubscription', (error, result) => {
      if (error) {
        if (isKnownError(error.error)) {
          return toastr.error(error.reason);
        } else {
          return toastr.error("An unknown error occurred.");
        }
      }
      this.setState({
        subscription: result
      });
    });
  },