diff --git a/src/unstated.js b/src/unstated.js index 2b3eb0c..c1695f8 100644 --- a/src/unstated.js +++ b/src/unstated.js @@ -13,8 +13,20 @@ export class Container { this._listeners = []; } - setState(state: $Shape) { - this.state = Object.assign({}, this.state, state); + setState(state: $Shape | (State => $Shape)): void { + const prevState = this.state; + const newState = typeof state === 'function' ? state(prevState) : state; + + /** + * allow either early return or ternary return of previous state to + * propagate correctly through component tree by not calling _listeners + * and leaving old state in place. + */ + if (newState == null || newState === prevState) { + this.state = prevState; + return; + } + this.state = Object.assign({}, prevState, newState); this._listeners.forEach(fn => fn()); }