Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
React Easy State is the fruition of my two years long journey with ES6 Proxies and meta programming. It is also a state management library for React.
The joy of simplicity
Easy State is a React state management library with no core philosophyâââlike functional programming or immutabilityâââexcept for one thing. It aims to be as close to vanilla JavaScript as possible ⊠and it got pretty close. You can store your state in simple objects, which may be used and mutated in any way you want.
Behind the scenes the state stores are wrapped by ES6 Proxies, which intercept all basic operationsâââlike property get and setâââand add a touch of reactive magic. They register which part of which store is used in which componentâs render and automatically re-render the component when necessary.
The cool thing about Proxies is transparency. From your point of view none of this is visible. You just have to deal with plain objects and React components and let Easy State keep them in sync for you.
Coding a stopwatch
âHello World!â is boring. Letâs make a dumb stopwatch instead.
First we have to create a clock, which serves as our state store. It should save how many times it ticked so far and it should be startable and stoppable.
import { store } from 'react-easy-state'
const clock = { ticks: 0, start () {this.intervalId = setInterval(() => this.ticks++, 10) }, stop () {this.intervalId = clearInterval(this.intervalId) }}
export default store(clock)
As I promised you, this is vanilla JavaScript ⊠except for store. store is one of the two functions of Easy State and it wraps objects with transparent, reactive Proxies.
Rule #1: Always wrap state stores with store before you export them.
We will also need a view to display our clock. Letâs go with the simplest option: a function component.
import React from 'react'import { view } from 'react-easy-state'import clock from './clock'
function StopWatch () {const { ticks, start, stop } = clock
return ( <div> <div>{ticks}</div> <button onClick={start}>Start</button> <button onClick={stop}>Stop</button> </div> )}
export default view(StopWatch)
Not much to explain. The clock store is a normal object, StopWatch is a normal React component. The only strange thing is view, which is the other function of Easy State. view turns your component reactive and re-renders it when a store property - used by its render -Â mutates.
Rule #2: Always wrap components with view before you export them.
You can try the live demo here.
I told you, itâs dumb⊠Time to make it shiny.
Become a master watchmaker
We have to add a bunch of features to the clock store. It should display the elapsed ticks in a nicer format, it should know when it is ticking and it should be resettable.
import { store } from 'react-easy-state'import moment from 'moment'
const clock = { ticks: 0, start () {this.intervalId = setInterval(() => this.ticks++, 10) }, stop () {this.intervalId = clearInterval(this.intervalId) }, get time () {const time = moment(0).millisecond(this.ticks * 10)
return { seconds: time.format('mm:ss'), fraction: time.format('SS') } }, get isTicking () {return this.intervalId !== undefined }, toggle () {this.isTicking ? this.stop() : this.start() }, reset () {this.ticks = 0this.stop() }}
export default store(clock)
Nothing very surprising, just a bunch of new JS code. Keeping the store framework independent is a nice idea. It lowers the barrier of entry for new devs and makes switching frameworks easier.
Letâs move on with the new StopWatch component. It displays the nicely formatted time from the clock and adds a reset functionality.
import React from 'react'import { view } from 'react-easy-state'import clock from './clock'
function StopWatch () {const { time, toggle, reset, isTicking } = clockconst label = isTicking ? 'Stop' : 'Start'
return ( <div> <div>{time.seconds}<small>{time.fraction}</small></div> <button onClick={toggle}>{label}</button> <button onClick={reset}>Reset</button> </div> )}
export default view(StopWatch)
The live demo is here. Still not rocket science, but it can compete with the big guys. Google âstopwatchâ, if you donât believe me.
The two rules of Easy State
Hopefully you start to see the pattern form the above examples. Easy State has two simple rules:
- Always wrap your state stores with store before you export them.
- Always wrap your components with view before you export them.
Apart from these two, you have total freedom. You can access and manage your state however you want to.
Under the hood
Easy State is a stalker, it secretly keeps track of two things:
- store tracks every property get and set operation on the state stores,
- view tracks the currently running render function.
When a store property is used inside a render function, it is paired with the render and saved in a tuple. Laterâââwhen the same property is mutatedâââit looks up all of its saved renders and executes them. This way the view is always kept in sync with the state.
Letâs move inside our stopwatch and see whatâs going on there.
- StopWatch is rendered for the first time. view saves the fact that StopWatch is currently rendering.
- StopWatch uses the time, isTicking, ticks and intervalId properties of the clock store during its render. All of these get operations are intercepted by the store Proxy and Easy State takes mental notes: StopWatch is using these properties to render.
- The user presses the Start button, which starts an interval and sets intervalId. The set operation is intercepted by the store Proxy, which realizes that intervalId (and isTicking) changed. Easy State re-renders every component, which relies on these properties. In our case, this means StopWatch.
- The interval increments ticks every 10 milliseconds. Easy State knows that StopWatch uses ticks and re-renders the component every time ticks is incremented.
Why should I try it?
Easy State is based on an old ideaâââcalled transparent reactive programmingâââwhich is used by VueJS and MobX for example. The innovation lies in the implementation, not the concept.
Both MobX and VueJS use ES5 getters and setters to track property access and mutation on the stores. This approach has limitationsâââlike arrays and expando propertiesâââwhich require workarounds from your side.
By using ES6 Proxies, Easy State can finally complete the magic of transparent reactivity. It can track anything from dynamic properties to delete operations, inherited properties, iteration, enumeration and property accessors. It wonât ruin the reactive fun with exotic bugs and workarounds.
If this article captured your interest please help by sharing it. Also check out the Easy State repo and leave a star before you go.
Thank you!
Originally published at blog.risingstack.com on January 24, 2018.
Introducing React Easy State was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.