I'm currently building an app where the core state is simply a tree of plain old mutable JS objects. We have all the expected disadvantages (mostly: no easy shouldComponentUpdate), but things are easy to reason about, otherwise. We found that stuff like "has the user expanded a dropdown" or "which auto-completeable search term has just been entered" works perfectly in a local component's setState. The idea is, basically, anything that the user doesn't care losing when navigating away from the current screen can go in a local component's state. This seems to go entirely against the functional immutability idea, but it significantly reduces the amount of updates we need to do to our big central data structure.
I'm going to build a new thing and I'm considering going the nice functional way. However, I can't see any downsides to using directly mutable state to simple, local, unimportant stuff.
Would you do it like that? Or would you avoid component state altogether and go with props only?
Interestingly, as your app state gets bigger, you are actually forced to use something like cursors for all state updates, for performance reasons. Naive immutability in javascript means clone-before-modify, which is far too slow when your state values are large. It quickly bubbled up in our profiler. Funneling all immutable updates through a cursor means the cursor can use structure sharing on the state value, skipping the defensive clone and preserving reference equality for equal subtrees. Also afaik, implementing a general shouldComponentUpdate (edit: in js) without something like cursors is not possible, because you need === equality for onChange props.