Our News

React EZStore

2/24/2016

written by Greg Pasquariello CTO

Simplified one-way store with SuperAgent integration

While Flux delivers a solid architecture for one-way dataflow, I find that it and it's related packages (Reflux, Redux, et. al) are simply too abstract to be practical for many applications. At Motili, we use this very simple package I call react-ezstore, to ease data flow and management. It provides a similar architecture to support one-way data flow, but in a much more useable and practical manner.

In addition, this package provides a native store which integrates directly with SuperAgent, in order to deliver net data following the same model. 70% of our stores are integrated with back-end services in one way or another, and this provides a simple way to fetch and save data.

Store

A "Store" is nothing more than a collection of data values and some additional functions. To use a store, you can simply create one with new Store({...}), passing in some collection of variables that you'd like to store.

A store has getState() and setState() methods, just like a typical react component, so its use is very familiar. In addition, it has a subscribe(listener) method, to allow your component to be notified of updates to the store's state.

A more typical use of a store is extend it, to add the kinds of functions you may need to process data in the store. For example, a new RegistrationStore might be used during a website registration process and contain a function to generate a random password:

Very simple stuff… stores are just basic JS objects with some functional conventions.

Service Stores

The react-ezstore library extends stores a bit further. Included in the library is a subclass of store called SuperAgentStore. This uses SuperAgent to make network calls (GET, PUT, POST, etc.), and delivers the result in a consistent, parsed object. If you've ever had to deal with parsing service call results and dealing with errors, you’ll understand how this can be useful.

To use it, we can simply modify the above code and add a function to post the registration data to a service:

When you call regStore.postRegistration(), it'll simply make the network call and notify your component when it's complete.

Component State

Typical react components render UI utilizing data in this.state. This works great in many situations, but sometimes falls down; for example, if you have a "wizard" type interface, it becomes difficult to pass state from one wizard page to the next. Or, if you have a control with a lot of state, all of which gets rendered, adding some controlled inputs (like text fields) can have the undesirable effect of re-rendering the entire state for every keystroke. This, in turn, can make the text field be unusably slow.

The EZStore library is not much more than a glorified state object with some handy features. Because of this, we can easily create a store (i.e. a state) that is shared amongst react components, and which each component can use as proxy for maintaining their own state. Because it's a separate object, it's easy to share the store between related OR unrelated components.

Mutators

One last thing… stores support 'mutators'. The future direction of React eliminates the LinkState mixin, so mutators can easily be used to replace them. A mutator is nothing more than a function that listens to change events from HTML objects, and updates the specified state accordingly. In react-ezstore, mutators are available on any store object, as follows:

In the example, a mutator updates the companyName value in the store state when a user enters data in the text field. Similarly, it updates the corporationType when a user makes a selection from our custom drop down component.

Mutators actually work with any object that has a setState() function, and can be used independently of stores. To set up your own mutator is nothing more than this.mutator = new Mutator(this);. If your object has a setState() function, the named state variable will get updated.

In addition to simply updating the value of the specified key, you can pass an additional function to the mutation, that will get invoked when the mutation is complete:

If lots of flexibility is needed, you can even create a FunctionalMutator that mutates it's own way:

Stores

One more last thing... react-ezstore also provides a Stores object to allow you to make stores available anywhere in your app. When you save a store to the Stores object, you can access it again later via a key:

That's all there is to react-ezstore! It's simple, but allows Motili to build (and maybe more importantly, maintain) React apps in a fraction of the time we've found when using other technologies.

You can get react-ezstore from https://www.npmjs.com/package/react-ezstore. To get updates about react-ezstore, follow me on Twitter @gpasq


Share this on Facebook!  Share this on Twitter!