Reactive Data in React Meteor Applications

March 09, 2016 0 Comments by

Meteor let's us publish data collections from our server. Browser clients subscribe to these publications. When the data in the collection is updated either by the user or an external source, these changes become visible to all subscribed clients. Each client has a copy of the subscribed collection in minimongo. Meteor checks the diff and Mergebox keeps track of all subscribed clients on the server.

How Much is too Much

Enough user publications will consume all your server memory if the CPU doesn't get completely consumed first. Determine memory threshold by counting the number of publications, the size of the data, and multiply by the maximum number of concurrent users.

The Mixin

The MDG has released a mixin where you define references to reactive data sources in a getMeteorData method. This becomes available in your component as this.data, instead of using this.props.

The mixin can be used in a container component and passed down to child components. Each time a component unmounts, the subscription will be canceled. The problem here is that when Meteor 1.3 is released, and ES2015 is used in your application, we won't be able to use the mixin with the ES2015 class construct. Mantra suggests we use a higher order component.

Component Lifecycle

- Call componentWillReceiveProps(nextProps) (if there are new props)
- Call shouldComponentUpdate(nextProps, nextState) (and maybe stop the update)
- Call componentWillUpdate(nextProps, nextState)
- Assign this.props = nextProps and this.state = nextState
- a method named observe() is called, and this.data is updated
- Call render() 

if reactive data source changes that was accessed from getMeteorData, the mixin calls forceUpdate() on the component

Higher Order Containers

A nice way to keep data and render functions organized, is to use container components. The container component fetches the data and pass this into the render component, which just handles the rendering. In Meteor we can use the react-komposer package.

import {composeWithTracker} from 'react-komposer';  
import PostList from '../components/post_list.jsx';

function composer(props, onData) {  
  if (Meteor.subscribe('posts').ready()) {
    const posts = Posts.find({}, {sort: {_id: 1}}).fetch();
    onData(null, {posts});
  };
};

export default composeWithTracker(composer)(PostList);  

Optimizations

Other strategies to consider in reducing memory consumption include:
- subscribing only for logged in users - making static queries for non-reactive datasets


Tag cloud