Easy State aims to make React's state management simpler without adding new syntax. To achieve this it makes the following modifications.
- It replaces React's
setState()
with plain native JavaScript. - It auto binds your component's methods.
npm i react-easy-state --save
Add the @easyState
decorator to all of your components - except stateless (function) components - and enjoy the benefits.
import React, { Component } from 'react'
import easyState from 'react-easy-state'
@easyState
class Counter extends Component {
state = { value: 0 }
increment () {
this.state.value++
}
decrement () {
this.state.value--
}
render () {
return (
<div>
{this.state.value}
<button onClick={this.increment}>+</button>
<button onClick={this.decrement}>-</button>
</div>
)
}
}
@easyState
is a decorator, which is not yet part of the JS language. You can learn how to enable decorators with babel here or you can use the older export default easyState(Comp)
syntax.
-
Your state can use any valid JavaScript. Feel free to use nested objects, arrays, expando properties, getters/setters, inheritance and ES6 collections directly.
-
The state is just an object, which updates synchronously when you update it. You don't have to worry about the asynchronous nature of
setState
. -
State mutations are picked up and they trigger the render method when appropriate.
-
The render method is only triggered if it is affected by state mutations. If it doesn't use the mutated part of the state or the mutation doesn't change the state, the render method is not triggered.
-
The render method is never executed immediately. Triggered renders are collected and executed asynchronously in one batch.
-
Duplicates renders are removed. A render never runs twice in one batch - no matter how many times it got triggered. Renders run in first trigger order.
-
Renders may trigger others renders by mutating the state. In this case loops are automatically resolved.
-
Renders always run before the next repaint.
-
Easy State implements an optimal
shouldComponentUpdate
for your components, so you don't have to worry about doing it by hand.
As a result the state is always fresh and a stable and fresh view is always achieved before the next repaint with the minimal number of required renders.
You can compare Easy State with plain React and other state management libraries with the below benchmarks. Generally it seems like Easy State performs a bit better than MobX, a bit worse than plain optimized React and similarly to Redux.
The list of benchmarks will expand in the future.
- Node: 6 and above
- Chrome: 49 and above
- Firefox: 38 and above
- Safari: 10 and above
- Edge: 12 and above
- Opera: 36 and above
- React native is not yet supported
- IE is not supported
Under the hood it uses the @nx-js/observer-util library, which relies on ES6 Proxies to observe state changes. Thanks to the Proxies it doesn't have edge cases or limitations. You can write any JS code without worrying about the render function. This blog post gives a little sneak peek under the hood of the observer-util
.
Contributions are always welcome. Just send a PR against the master branch or open a new issue. Please make sure that the tests and the linter pass and the coverage remains at 100%. Thx!
This library is a side effect of the front-end framework I have been working on in the past year. Please take a look at the NX Framework if you have some time. Have a nice day!