

Best practices for building large React applications - mtschopp
http://blog.siftscience.com/blog/2015/best-practices-for-building-large-react-applications

======
guscost
Some great ideas, especially the examples of breaking down UI into smaller
components. Thanks for writing this.

I've been using Flux to manage pretty much all of the application state, and
pass it to the top-level component and down through the tree of components as
props. This idea was very well described in an older article[0]. I would add
that this approach makes shouldComponentUpdate very important, since more of
the tree is rendered on every change.

Your example of the dropdown state is a great counter-example where Flux is
not necessary or even helpful, and in fact I've used the same example when
explaining it myself.

One thing I'm not sure about is whether the save action should use a callback
(or Flux ActionCreator), or whether it should be triggered by comparing the
values in componentDidUpdate as you suggest. Making that behavior declarative
is certainly appealing, but I'd be worried that an action like a save could be
idempotent, with unpredictable side effects, and therefore makes more sense to
be explicit/imperative? I'm not sure which one would be easier to work with at
very large scale, and it looks like your application is larger than any of
mine, so perhaps the declarative style works better. If anyone has more to say
about this I'm curious to hear opinions.

[0] [http://aeflash.com/2015-02/react-tips-and-best-
practices.htm...](http://aeflash.com/2015-02/react-tips-and-best-
practices.html)

~~~
k__
Also, if it is in a "did update" method, doesn't this imply that the
components state has already changed?

------
findjashua
I like me some React, but my only gripe w it is the synthetic events, which
can result in a single model's state being updated by multiple listeners.

I have replaced synthetic events w event streams, and couldn't be happier w
how much cleaner the code has become as a result of replacing setters with
stream-combinators.

The architecture roughly follows Elm's Model-View-Update, by splitting each
component into view.jsx and update.js.

1\. Update contains the eventstreams (replacement for synthetic events), and
are transforms them into update-streams.

2\. The model combines multiple update streams to return a model-stream.

3\. The view combines multiple model streams, and the subscriber at the end
does a `setState` to trigger the re-render

Using streams also has the side-benefit of not needing the didUpdate,
shouldUpdate etc lifecycle hooks.

Here's a gist w the eventstream code:
[https://gist.github.com/findjashua/e78063e6591a2c234919](https://gist.github.com/findjashua/e78063e6591a2c234919)

Happy to answer any questions.

Edit: special thx to Andre Staltz for the insightful discussions.

------
jxm262
> Flux is also quite verbose, which makes it inconvenient for data state,
> state that is persisted to the server. We currently use a global Backbone
> model cache for data fetching and saving but we’re also experimenting with a
> Relay-like system for REST apis. (Stay tuned for more on this topic).

What do they mean by this? I _think_ I've been doing something similar on my
projects lately. Using Meteor as my backend pub/sub model, and React.js as my
front end. Ties together pretty nicely although there's a range of other
issues I'm still trying to work out (1 test frameworks for both React and
Meteor code, etc..)

~~~
chowes
The 'vanilla' implementation of Flux is very verbose, due to its declarative
nature

The Relay system they're talking about is in reference to
[http://facebook.github.io/react/blog/2015/02/20/introducing-...](http://facebook.github.io/react/blog/2015/02/20/introducing-
relay-and-graphql.html), which is how Facebook manages data fetching at the
component level.

~~~
jxm262
Oh yeah I get the part about flux being verbose :) Probably should have
omitted that part and just asked about what they meant by the Backbone model
cache.

Thanks for the link! Wasn't even aware of Relay.

~~~
ville
Relay technical preview was open sourced today:
[http://facebook.github.io/react/blog/2015/08/11/relay-
techni...](http://facebook.github.io/react/blog/2015/08/11/relay-technical-
preview.html)

------
porker
Here's the link to last time it was discussed (3 months ago):
[https://news.ycombinator.com/item?id=9515392](https://news.ycombinator.com/item?id=9515392)

------
hellbanner
Any examples of good tile-based board games written in React (or other JS
frameworks)?

~~~
ArthurClemens
An example is chessground [1], the UI for the lichess [2] chess game, written
with Mithril [3].

[1]
[https://github.com/ornicar/chessground](https://github.com/ornicar/chessground)
[2] [http://lichess.org](http://lichess.org) [3]
[http://mithril.js.org](http://mithril.js.org)

~~~
hellbanner
Thanks & thanks @mikemintz & baddox, this is exactly what I'm looking for.

------
vkjv
"If you find yourself duplicating/synchronizing state between a child and
parent component, then move that state out of the child component completely."

I have exactly one exception to this rule and I would love is someone could
provide a recommended way to _not_ make it an exception. Debouncing. For
example, if you have a input field that lets you type a number for pagination,
debouncing the change of that value with the displayed copy of it.

This is implemented with a debounced input field type that uses props to get
and update the value, but maintains it's own state for what is displayed. It
uses `componentWillReceiveProps` to stay in sync.

EDIT:

After re-reading, it looks like the author uses this exact same exception for
the "select". This is considered UI state and should be fine.

------
Sir_Cmpwn
For what it's worth, there's also a componentWillUpdate, which I find better
than componentDidUpdate and comparing with the previous state.

------
dmk46
@Sir_Cmpwn I agree, only it's a shame you can't set state in
componentWillUpdate, only in componentDidUpdate.

------
aikah
never understood why React needed flux on top. Or does that mean React doesn't
solve the problem it is supposed to solve on its own ? or flux should have
been baked in react? never understand what flux was about anyway.

~~~
WalterSear
Flux is a way to organize interactions with data and business logic, so that
React only has to worry about the UI. Specifically, it breaks down behaviours
into functional streams that don't interrupt each otherr.

~~~
aikah
so what is relay ? is it on top of flux ?

~~~
WalterSear
AFAIK (I have not worked with Relay yet) Relay is a data layer, (which
currently flux handles already). Relay is component based, as opposed to flux,
which handles data in a top-down manner.

As I understand it, when we implement Relay, flux will be relegated to
handling UI behaviour and changes. So, React would handle DOM manipulation and
rendering, Flux will handle user behaviour and changes to state, and Relay
will provide the data.

