Composing modular States with React Unstated

Yarden Hochman
2 min readMay 17, 2018

--

Until recently, the main method for imbuing React Components with shared state was to wrap them in Higher Order functions, that inject them with it. Recent developments have introduced a shift in this paradigm, introducing new, seamless methods for imbuing state as well as other props, and it all starts from the render prop API.

HOC out, Render Props in!

In “Never Write Another HoC”, Michael Jackson, who developed React Router, has stressed the need to wean the community off of its over-reliance on Higher Order components by replacing them with the Render Props method. Here’s how this looks like:

Following Recent trends, Apollo library’s recent release shifted from HOC to render props

It was shortly after this talk that React v16.3.0 came out with a new context API, which uses the render props method to expose state and class methods to portions of the component tree, rather than the entire application as with Redux.

Classes without render methods

On our quest to build performant, modular apps, we separate stateful container components from our stateless view components. The main issue React developers tackle is finding elegant ways to expose class state and methods to external view components.

In Redux we use stores and reducers instead of class methods and states, but what if instead of replacing classes with Redux logic, we could decouple classes from the view by replacing the class render method with render props?

A new library called “Unstated” has come out with a way to do just that. Feel free to check out Unstated’s Github docs and continue to some use cases demonstrated below.

User Class

When defining a user class, the user business logic is separated into it, allowing other components in your app to remain isolated from its implementation details. Here’s how it looks like with Unstated:

A container completely separate from view components. Notice the lack of a render method

You might want to check for user cookies when the app launches.

This can be done with Unstated’s inject method:

Any user state we subscribe to will now contain the user from the cache by default

Modals

When we think about Modal states, we can pretty much break them down into “add modal (x)”, close open modal”.

Unstated allows us to define the container state for all modals, and then create a state instance for each modal we need to use!

This method allows us to define a model for modal state, and then create separate instances of it for each modal in the app.

Forms

In most cases you’ll want to manage forms using the local React state. However, sometimes different components need to be able to fill the same form from different branches of the component tree. Here’s how an Unstated Container will look like in such a case:

Pretty simple isn’t it?

You may not need Unstated

Unstated is new. A more mature and documented library such as Redux might serve you better. This writer hopes to show where the React space might be heading, as well as provide an example of where you might find yourself on some future project.

As a final note, here’s an example that combines Apollo’s Query component, a reusable load and display component, and an unstated component, that feed of each other before finally rendering the view.

This component will load the relevant project page based on the match.params prop inherited from React Router, display a temporary “loading” message until the data is ready to be passed to the project state, which will be subscribed to the project view.

--

--