Meteor 1.3 and React composition with reactive data sources

Not sure if this helps, but I was getting a similar error message on upgrade to meteor-1.3.rc-3. I had to delete my app node_modules directory and run npm install again and then the build completed.

Thanks, that fixed it.

The react-meteor-data package requires that you NPM install react-addons-pure-render-mixin. Will be looking to message this a little better, but for now you can just do npm install --save react-addons-pure-render-mixin.

1 Like

I had the react-addons-pure-render-mixin package installed but I guess had cruft in node_modules that was somehow interfering. Allā€™s working now.

Minimongo fetches certainly can be slower than they could be (if for instance they had indexes), but in theory ā€œshouldā€ always be fast. I tend to think if your data function is realistically causing the kind of problem you reference here you should probably take steps to optimize it. @mitar has some great tools to cache reactive results for instance.

I can see the point that itā€™s maybe a simpler experience to just pass a set of reactive functions into your component than deal with caching yourself, but the issue I have with it is that it moves the ā€œreactive horizonā€ inside your otherwise ā€œpureā€ presentational component. Now your component is re-rendering without its props changing, which violates the norms of React and means that things like pure-render-mixin and the dev tools other debugging tools canā€™t really help you as they otherwise would.

Iā€™d love to hear a real-world example of when a reactive datasource takes significant amounts of time to calculate (not saying I donā€™t believe it happens, just itā€™s good to have a solid example).

At Workpop our reactive data comes from subscriptions as we are leveraging Redux for all client state we really only need a container that works well for subscription loading. ReactMeteorData works fine for this instance, I was just hoping we would see some amazing solutions having waited so long for nothing to move. Again, Tom, not your fault inheriting other peopleā€™s projects suck.

Iā€™d like to share how we created these subscription containers,

Essentially stealing tons of code from template.subscribe, we built a container very similar syntax to Reduxā€™s connect function. We can easily swap ReactMeteorData vs TrackerReact in this example, as we are only dealing with one reactive function for the container.

1 Like

or sequentially blocking, which makes the lack of indexes even worse :laughing:

I really wonder about this, at first glance in the testing code you wrote, your usage seems right. From glancing at the TrackerReact code, it shouldnā€™t work the way you are seeing in the console results. Maybe @dinos can take a look at your actually repo and point out some issues? Also, perhaps it would be easier to use console.time instead of all the time tracking you are doing?

I also think now after using TrackerReact that perhaps having automated ā€˜loadingā€™ messages while waiting for data to return is worth something here, so perhaps React-Komposer has the right idea out of the box.

Just want to add quickly that since TR runs atomish along singly reactive methods, having a loading message most often not more than a check ā€œif the data is there yetā€. Because subscriptions can also be established but the data not completely fetched.

Of course that could be fancierā€¦ again, thinking of a TR sugared component as a HOC

These are two different things. Iā€™m also a big believer in the HOC pattern for these exact reasons, and the example I gave is indeed a HOC that takes a pure presentation component as an argument:

@JeremySaks added an example using react-composerā€™s composeAll with multiple composeWithTrackers - essentially the same thing. With an extra helper func that could be part of react-komposer, we can get a similar pattern, which again, is still a HOC but divides up the reactivity (which to me feels more natural in Meteor):

The issue is still just unnecessarily rerunning every reactive computation any time any one of them changes. I can give a theoretical ā€œreal worldā€ example, if youā€™ll accept that :>

Say we have a dashboard, with 8 mongo queries and 1 checkbox to show Celsius or Fahrenheit (used by a formatting component) and 1 dropdown to choose the theme. Changing the checkbox or dropdown will rerun all 8 queries, even though theyā€™re going to get back exactly the same results. Every time a new row comes in on 1 query, the other 7 queries will all rerun too. For smooth JS animation, we can only block for a few ms max, and on mobile, everything happens slower. This would affect UX.

I feel I have to emphasize that this discussion really isnā€™t about me; Iā€™m a long time developer who understands these concepts well, and Iā€™m never going to have an issue. The question is what the official recommendations should be. It reminds me of iron-router vs flow-router. Iron-router always worked perfectly for me because I understood it well. But many, many people had issues with data() causing undesired re-renders. Flow-router came and forced people to write performant patterns, and people liked that.

@dinos, regarding the earlier issue, can you clarify, does TrackerReact have a single reactive computation or one for each helper?

4 Likes

@gadicc, well of course not a single one for a single method, but that is the beauty of javascriptā€™s event-driven nature. Essentially its a stop-and-go reactive computation due to the use of non-reactive. Meaning: One data source is ready, its invalidated and served, stops, comes the next one ready, invalidation is triggered and served, stops, and so onā€¦

PS & OT: Iā€™ll post later in the other thread (on my phone now) but I have issues with ā€œunrecognized tokensā€ with ecmascript-hot. I tried it out last night because auf HMR and babelrc. The false-positives are hitting me.

Right I understand, that if Iā€™m using official container wrapper, then better for performance to put few smaller containers rather one big?

@dinos, thanks for the quick reply. Sorry, I didnā€™t totally understand. So if I have multiple ā€œhelpersā€, and one invalidates, should they all be re-run again or not? :slight_smile: If you have a chance, Iā€™d love you to take a look at the example.

(And yeah, sure, post on that threadā€¦ if the stateless thing is breaking, you can just comment out the react-transform in your .babelrc for nowā€¦ or change your functions slightly if thatā€™s an option. Iā€™ll try make this more optional in the future).

@joshowens, amazingly Iā€™ve never used console.time() beforeā€¦ old habits die hard :> It looks like it varies a little by browser though.

Iā€™m not sure about libs, but certainly plenty of mind-share and talks around building container components and regular components: https://medium.com/@learnreact/container-components-c0e67432e005#.m5dzp3rmkā€¦ Just sayin @sashko

Yeah, I agree that if you are building your own container thatā€™s a great approach. I was asking about specifically data integration libraries.