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
});
});
},