Another pattern for loading data in react


#1

You might have encountered this post about how to load data in react https://www.discovermeteor.com/blog/data-loading-react/

I found myself using a different pattern, where concerns are separated yet in an other way:

  1. How to load data (subscribe and minimongo query, or meteor command, or graphql, or redux)
  2. How to react to when data has been loaded (tracker, promise, callback)
  3. What data is needed when and how to deal with the current data availability (loading vs. loaded)

In particular I believe that number 3 actually belongs to the component. Classic “dumb components” are just a little too dumb. In reality a component intrinsically knows when it needs a post’s comment (the comments section) and how to deal with their absence (show a loading bar)

Each of the approaches in the post above breaks one of the principles:

  1. getmeteordata breaks 1 and 2
  2. trackerreact breaks 1 and 2
  3. react komposer breaks 3
  4. document container breaks 1

So I’ve been using another system, which looks more or les like this:

class Post = ({postId, Posts, Load}) => {
	<Load
		data={() => Posts.post(postId)}
		loading={() => <Loading/>}
		get={(post) => (
			<div>
				<h1>{post.title}</h1>
				<div>{post.content}</div>
			</div>
			<Load
				data={() => Posts.postComments(post)}
				map={(comment) => (
					<div>{comment}</div>
				)}
				empty={() => <div>No comments</div>}
		)/>
}

as you see one can switch out the implementation of Posts and Load (say from a subscriptions based model to a graphql based model or to mockups for tests) and the component still has the choice about what data to load and when. Load has various utility methods for different situations (get when you need one item, map to iterate over an array, empty when the result is empty…) but a minimal solution would only have a handle to just deal with the raw data).

An added benefit is that you don’t necessarily have to split your components into multiple components whenever there is some data to be loaded, which at the beginning, while prototyping, can give you a nice productivity boost.


React wrap element with state