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.