Revisiting Meteor, but have a dilemma in React

I’m mostly finished with a new Meteor app for a client. My first Meteor app in a number of years. Man, I forgot how I used to love Meteor. I still do. The app is looking fabulous, client happy, all that. Using React.

So I hit this weird area, building this component that displays a number of cards to the user. Each card has some enrollment data on it for individual camp information (the client is a music camp that enrolls participants). The January card has data for that camp, the March card had data for it, etc. 16 camps in all. The client wanted this info real time because they get inundated with enrollments at certain times and it was important to have the enrollment numbers up-to-date as people are enrolling.

My original thought was that this component could get slow, but it turned out OK. It’s read-only data, not changeable by the user.

So, the publication is simple enough. It’s publishing the last two years of camps in the ‘programs’ collection.

In the component, within the componentDidMount, I have the subscription with the Tracker.autorun().

Meteor.subscribe('programs', () => {
  this.MayiTracker = Tracker.autorun(() => {
    const mayi = Programs.find({ CampYear: 'mayi19', Week1: '0'}).fetch();
    ...
    ...
  });
  this.JuniTracker = Tracker.autorun(() => {
    const sepi = Programs.find({ CampYear: 'sepi19', Week1: '0' }).fetch();
    ...
    ...
  });
  ...
  ... 
})

componentWillUnmount() {
  this.MayiTracker.stop();
  this.SepiTracker.stop();
  ...
}  

At this point I was aware that although I was stopping the Trackers, I wasn’t sure if the subscription call would be stopped by default. Would I have to stop it manually as well?

Anyway, everything working as expected. Cards loading data pretty quick (about 3 seconds in production environment) considering the number of sockets that had to open. But then someone reminded to me that I had the separate Trackers within the subscription call. I had remembered it backwards.

So I got busy reversing them, putting the separate subscriptions and Mongo queries inside one Tracker.

this.IntermezzoTracker = Tracker.autorun(() => {
  Meteor.subscribe('programs', () => {
  ...// Mongo query, etc.
  ...
  });
  Metero.subscribe('programs', () => {
  ...// Mongo query, etc.
  ...
  });
});

Alrighty then. Redeployed online to test again. But data loading into the cards was at least twice as slow. 7 to 8 seconds to get the cards loaded with data. The way I had it before was far superior in terms of getting the data loading on the UI.

Can any of you Meteor Monsters out there fill me in on what’s going on? If the first way is used, is stopping each Tracker all I need to do on un-mounting? Why is the second way so much slower?

Much appreciated. And long live Meteor.

1 Like

Meteor works well with React.
React hooks is cool and new meteor/react-meteor-data package is awesome.
You should try useTracker with React hooks. And if the data is not reactive, try to load the data via Meteor methods instead of publish/subscribe.
I designed my meteor web app to subscribe only one document (subscribe with _id value or some “key” value), not a list of documents, then fetch updated data via method and it works very well.

3 Likes

You’re trying to integrate with Tracker they way you would have done with Blaze. This is not the way to go in React. Please read this:

And I agree with @minhna: only use reactivity if you really need it.

2 Likes

Ouch ! Imho, too many subscriptions for the same collection ->

1 Like

Ouch is right. But after perusing over the docs, I’ve got myself up to speed with withTracker and have converted my components. A huge saving is code. And much simpler to understand, with more speed. Someone had told me in the past that Tracker.autorun was comparable to withTracker and both got the job done. Well, that’s not quite true, as I found out. I witnessed the bug a few times with the Tracker inside React components. Most of the time it would work, but sometimes it acted oddly.

Yes, the client wants realtime for this UI and knowing her business, I can see why. They also have a chat room where I obviously needed it.

Thanks for the links to mongo aggregation. I’ve known about it for a long time, but never thought I needed it. Will give a look.

Thanks to waldgeist and minhna as well.

3 Likes

I don’t see anything overly complex here that would require the use of aggregation. I think this will just come down to switching to the proper paradigm required by React as opposed to what you might be used to with Blaze.

If you needed further help at any point, I’d be willing to take a closer look at your code and make recommendations.