
Why is setState asynchronous? - stablemap
https://github.com/facebook/react/issues/11527#issuecomment-360199710
======
ambrop7
A (presumably controversial) way to use React is to use only props never
state, manage state in your own variables (possibly in a separate "controller"
class) and call forceUpdate() when you have changed those variables such that
the render would change.

This gives me flexibility to structure the code how I want. You can have the
separate "controller" classes deal with operations (like API requests) and the
"react class" mostly deals with display - it delegates actions to the
controller and retrieves data from the controller. This can promote code
reuse, notably certain components can share the controller class (not
instance) when you have similar logic.

As a more general principle, I like react just fine as a way to express the
DOM in a functional way and for its magic of figuring out just what parts of
the actual DOM must be updated; but I don't really care about how React wants
me to write code in other aspects, like where and how I should manage my data.

~~~
GeneralTspoon
Actually, using props instead of state is a pretty common thing to do - it's
how redux integrates with React [1]

[1]
[https://redux.js.org/docs/basics/UsageWithReact.html](https://redux.js.org/docs/basics/UsageWithReact.html)

~~~
zukzuk
... but also a very bad idea in practice, as most devs eventually find out.
Using the Redux store in lieu of state spreads code that could otherwise be
self-contained all over your codebase. It's a good way to make a huge mess and
write some very brittle code.

~~~
nemothekid
I’ve managed a huge React app with Redux and never came across this - I can’t
imagine how your case would come up. Even though we use a single state object,
the concerns of a single piece of state tend to be contained in its reducer
and component only.

~~~
jlewallen
Do you maintain a 1:1 relationship between reduced state and components? I'm
curious because your word choice seems to imply you do and I'm wondering how
popular that is if so.

~~~
nemothekid
I'll be honest - I'm having trouble parsing what having a '1:1 relationship
between reduced state and components' actually means. The most common "state"
in our application is the result of a GET request (for example, you need some
data from the server), and an accompanying loading/loaded/error state.

Most (presentational) components will load its needed data from a container
component (through connect(), or other higher order components we developed).
So for example, a given `user` object, could have its data in a chat
component, or an analytics view, or a settings profile. The reducers aren't
generally concerned with how the data is used, just that its available to
anyone who asks.

As far as localized state goes (like a form), we took a page from reduxForm
(and we use reduxForm) - if there were times we needed to use setState a lot
(for example, we had a query builder and chart components), we built a higher
order component (like connect), where you would pass the props you need, and
that component would figure out how to query it and make it available in the
redux state. Again this meant you could create a "query object" from one
component, that was theoretically available to any other component (as part of
the Redux tree), if they asked.

All in all, I never considered any sort of 1:1 relationship between state and
components. I had state, and the components decided what state they needed and
rendered themselves appropriately. This was a fairly complex SPA that had real
time chat, analytics and CRM-like features, there were 100s of components.

Our codebase was far more robust from the Angular version we had rewritten it
from a year ago (a component crashing didn't bring down the whole app), and
the concerns for every component tended to be self-discoverable (we were able
to hire interns to start hacking on it within 2-3 days, after they wrapped
their head around redux). I'll admit it took me sometime to understand the
benefits of Redux, and there was a lot of ugly boilerplate until we started
using higher order components, however "brittle" and "messy" is the last words
I'd use to describe the codebase.

~~~
bryanrasmussen
From a flux/reflux perspective I'd 1-1 relationship to mean that every
component had a matching store, but since Redux has a single store not sure
what pattern would match.

------
josephorjoe
They really should have just named it `queueStateChangeRequest` instead of
`setState`, since it does the former and not the latter.

------
rootlocus
The title should probably mention the technology the question is referring to.
This isn't a javascript forum...

~~~
cryptonector
The linked comment is very meaningful and comprehensible even if you're not a
web developer (which I'm not). The only word in the title that may not be
immediately meaningful is "setState", but the rest is still a huge draw for
anyone who has had to deal with async code.

~~~
halayli
you’re arguing nonsense just for the sake of arguing. if someone hasn’t used
react before then the title is meaningless.

~~~
cryptonector
I haven't used React before and the title _definitely_ grabbed my attention.
The linked comment was _very_ informative to me, even though I'm not a UI dev.

------
admax88q
JS is a mess.

I think this blog post highlights the frustrating viral nature that is async
functions:

[http://journal.stuffwithstuff.com/2015/02/01/what-color-
is-y...](http://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-
function/)

~~~
cryptonector
JS is a mess, but async messes aren't JS's fault. Async is hard, but also
everything just has to be async -- there's no way around this really. If you
write sync code and later you need it to be async, then you're in for a full
rewrite. If you write async code and you later need a sync version then you
just add a wrapper that waits for completion.

In a world of fast CPUs, slow memory, distributed computing (whether
client/server or peer-to-peer), remote function as a service, ..., asynchrony
is a hard requirement.

The GUI event model has been with us since... even before the days of X11.
Asynchrony in the UI is and long long has been a hard requirement. Users
_hate_ synchronous UIs, and rightly so.

Asynchrony is also difficult. But it's not like sync + threads is a panacea --
it's not because threads are way too heavy-duty. Better to deal with the pain
than to deny the need.

~~~
blowski
Rubbish! You could make the same argument for parallelising, abstraction,
logging, and just about every other feature. But then you’d never build
anything because there are infinite possible features you could include.

Build only what you need today, and prepare for what your employer says you
will need tomorrow. Anything else is like saying everybody should buy a jeep
in case they move to the countryside.

Async brings its own costs. Unless your employer benefits, you are costing
them money by giving them features they don’t need.

~~~
cryptonector
You have to think at least a bit ahead. Better to write thread-safe async code
from day 1 than to rewrite later.

~~~
blowski
YAGNI -
[https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it](https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it)

I’ve worked with plenty of valuable apps not using async. If the requirements
change such that async becomes the best way to solve the problem, that’s
something the business would decide at that point.

~~~
cryptonector
Sometimes you can think ahead and see the need coming -- or not coming -- and
act accordingly.

Experience is helpful here.

When I have to write C I try to at least write thread-safe C close to
something I could expose as a library. I've had too many cases where I or
someone else wrote code they NEVER thought would be needed as a library,
therefore took all sorts of liberties, and then suddenly there was a need for
a library to do what said code was doing. Oops. I've run into fewer instances
of sync code that turns out should really have been async and where adding
threads isn't good enough, but I've still run into some.

This isn't about _functionality_ \-- this is about scalability. When you know
you need to scale, you have to think ahead about it.

~~~
blowski
A lot of projects are little more than crud with a few complicated business
rules. Use a framework with a good caching layer, and a lot of the time the
employer is very happy with the outcome. It’s cheap to build, maintain, and
host.

But then along comes a developer who says “we must build this app with async
so we can scale”. Suddenly the junior devs build an absolute mess because they
don’t know how to work effectively with async. So a few seniors get involved.
Then the project runs out of cash.

Sure, some projects benefit from async and some fundamentally require it. But
not all of them, I doubt even the vast majority of them.

You only need to scale when you’re successful, and most applications are not
successful.

