
React JS Best Practices - lopatin
http://blog.siftscience.com/blog/2015/react-applications-that-scale
======
girvo
_> Flux is also quite verbose, which makes it inconvenient for data state,
state that is persisted to the server._

We felt the same way, until we moved away from Facebook's Flux implementation
and adopted Flummox[0]. It's singleton-free, so we gained isomorphism for our
application with only a tiny bit of extra work, and it hides away the
dispatcher (unless you need it, which we haven't despite having over a dozen
stores, tonnes of actions and a large number of components).

With Flummox making it so easy, we put all state into a store. This allows us
to save application UI state to localStorage, bootstrapping the app into the
same position the user was previous, with again no extra effort on our behalf.
It's well worth checking out!

[0] [http://acdlite.github.io/flummox/](http://acdlite.github.io/flummox/)

~~~
cnp
Oh holy shit I just moved my app off of reflux and on to flummox and wow! Much
better

~~~
arms
I'm also curious to hear why you like Flummox better than Reflux. I'm using
Reflux now, and haven't hit any pain points, which I can't say the same about
some of the other Flux implementations.

~~~
cnp
When I started investigating isomporphic strategies with Reflux I stumbled
upon this thread
([https://github.com/spoike/refluxjs/issues/144](https://github.com/spoike/refluxjs/issues/144))
which made me realize that if I didn't switch quick I would have some terrible
technical debt on my hands in the coming months. I started looking for
alternatives and found Flummox, which is lightweight, isomorphic, and written
for the future via ES6-7 features like async await and classes. (Once you
start using ES6 classes with ES7 classProperties turned on via Babel -> stage
0 you'll never want to go back to the old way of writing things.)

------
supercoder
Having just started using React for a new project, I absolutely love it.

This new project uses a Rails backend, with React allowing the web to act the
same way as any other client (iOS app, Android app etc), and it's so
productive to work in.

Pretty much decided I won't be writing a web app any other way for any future
work.

These best practices look pretty good, though my advice to any beginners would
be to not get too bogged down in worrying whether you're doing things 100%
right as React can be pretty forgiving in refactoring later on.

~~~
Hytosys
>Pretty much decided I won't be writing a web app any other way for any future
work.

Careful what you wish for!

------
iyn
One of my initial problems with React & CSS was styling :hover etc. For now,
Radium [0][1] solves this problem, but IMO as a community we're still trying
to figure out all the best practices and patterns, when it comes to building
isomorphic webapps (or webapps is general, since React introduces new way of
building apps and I'm sure that's just the beginning).

[0]
[http://projects.formidablelabs.com/radium/](http://projects.formidablelabs.com/radium/)

[1]
[https://github.com/FormidableLabs/radium](https://github.com/FormidableLabs/radium)

~~~
pbowyer
Why did you want to do it this way, rather than using CSS classes and a
stylesheet? I've read the Radium intro and I still don't get their use-case.
To me it feels like a misunderstanding of CSS, so inlining it in the component
makes sense to the programmer.

~~~
iyn
This is a great question, I used to think exactly the same until I became
enlighten ;). Well OK, to be honest I'm still not entirely happy with how
things are modularized, but I see advantages. This is a very good presentation
which explains key ideas: [https://speakerdeck.com/vjeux/react-css-in-
js](https://speakerdeck.com/vjeux/react-css-in-js)

Understanding the problems mentioned in the slides was literally eye opening.
I was already trying to solve the problems with CSS, without fully realizing
that I'm solving them. For example, my "solution" to namespaces was creating a
naming conventions for all classes/IDs, like ".header-search-box-button" and
this approach becomes PITA quickly. Also, after a while I had more and more
dead code, which wasn't easy to identify and I couldn't be sure that if I
remove some class, I don't have any elements that depend on it. Non-
deterministic resolution was also an issue for me - say user was on a page A
(therefore had loaded A.css with class .main-button) where particular boxes
are blue. If the user goes to page B (we load B.css which also has .main-
button) he should have red boxes. But if the user gets back to page A, the
boxes that are supposed to be blue are red (browser cached the style and when
browser have 2 classes definitions, the one that was loaded the last "wins").
Sure, we could use IDs for everything, bundle all styles into 1 file etc., but
bigger sites would have like 5MB CSS file and at the end of the day it's still
hard to maintain the codebase.

I'm sure that "normal" way works for regular/medium sites (it worked for a few
good years, right?), but I see ton of advantages for using the inline styles
in the JS. It's not easy to "convert" to new approach, but I honestly don't
look back. As I've said - it's not ideal solution, but a very important step
forward.

This is a good 3-part tutorial on react, flux and some other things:

[https://www.youtube.com/watch?v=Pd6Ub7Ju2RM](https://www.youtube.com/watch?v=Pd6Ub7Ju2RM)

[https://www.youtube.com/watch?v=iR22EWW-
CVc](https://www.youtube.com/watch?v=iR22EWW-CVc)

[https://www.youtube.com/watch?v=6fhTawDEE9k](https://www.youtube.com/watch?v=6fhTawDEE9k)

~~~
Geee
What do you think of [http://www.basscss.com/](http://www.basscss.com/) and
would this kind of CSS be helpful in the situation you described?

~~~
iyn
This is the first time I saw Basscss, so take all this with a grain of salt.
It seems well written, but I would put it in the same/similar category as for
example Bootstrap. Basscss seems to be more modular - you can build your own
"version" of Bootstrap - but Basscss gives you npm modules, so you could do
something like/equivalent of require(basscss-grid). So, there are some
differences that can be interpreted as a advantage of Bootstrap/Basscss, but
react tries to solve the bigger problem IMO. Did you see that we're adding
more and more "logic" into CSS (like animations calculations, :first, :even
etc)? Where is the line? Does CSS is still "only" description of the
presentation or something more? To be honest, I don't know where we are now,
all those things start to merge/mix. I'd say that we're still on a quest to
find the best paradigms for the web. "Regular" HTML, CSS and JS were working
fine, but we're moving forward and new problems arise (how to handle different
screen sizes, how can 1000 people work on the same code base, ...), so we're
trying new solutions (like react and flux).

So, to answer your question: Basscss could help with some of the problems with
CSS but I think that react solves problem on a higher level and does it better
than any other solution we have now.

~~~
Geee
BassCSS is very different from Bootstrap or any other CSS framework. It's more
like "classed inline styles", so you build your element styling like 'border
border-blue blue bg-white p1 m1' (blue border, blue text on white background,
1 unit padding, 1 unit margin) e.g. you mix-and-match different CSS classes to
style your elements.

So, I was thinking using React + BassCSS, and build the class string in my
React components. Not sure if it makes sense, but at least it would probably
be a bit more manageable and faster to develop than inline styles. Inline
styles could be added on top of that of course.

~~~
iyn
If that's the case, I stand corrected. But the thing is, I still consider
Basscss a solution from the "CSS world". React, IMO, takes it to the next
level and combines inline styles with JS features (simple example:
[https://youtu.be/7YwmS0ny-58?t=58m38s](https://youtu.be/7YwmS0ny-58?t=58m38s)
\- the scalable font can be done in pure CSS but I could imagine more complex
use cases). Still, everybody picks the tools that are best suited for the
problem and his/her preferences.

Have you checked Radium
([http://projects.formidablelabs.com/radium/](http://projects.formidablelabs.com/radium/))?
What don't you like in this approach, if I may ask?

~~~
Geee
Yep, Radium looks pretty cool for dynamic styling.

------
rattray
I would love to see their HoverCard and similar components open-sourced, or at
least shared in a gist. Many of their abstractions sound great &
generalizable.

~~~
pbowyer
Open sourcing a library of components would be fantastic.

------
lopatin
Author here, happy to answer any questions or discuss further!

~~~
nthitz
Hi, how does React work with other libraries that modify DOM state
arbitrarily? How might d3 dom changes or canvas context calls work with React

~~~
lopatin
Nice, we're actually posting a tutorial in a week or two about how we use d3 +
react. I'll try to summarize though.

In the case that a library modifies the DOM, we try to keep React out of it's
way. React works best when it has full control of the DOM. In these cases,
React components are more of "wrappers" for the 3rd party libraries. Mostly by
using the componentDidMount/componentWillUnmount to initialize/destroy the
third party library, respectively. And props as a way of giving the parent a
way of customizing the behavior of the third party library that the child
wraps.

~~~
lobster_johnson
We use Google ads in our React apps, and it turns out to be a problem. I
wonder if anyone has solved it in a satisfactory way.

Basically, with GPT you have named slots identified by their DOM element IDs.
You can "refresh" a slot any time, which will populate the element if it's
empty, or load a different ad.

So we do that when we're mounted. Unfortunately, if the page structure
changes, React will re-render the component and blow away the contents --
anything GPT has put in the element is considered alien.

That's fine, we just refresh. The problem is knowing _when_ a render has
finished and the ad element is empty. In my testing, React elements would
often have a delay after which their changes have been applied to the DOM; so
I use setInterval to check repeatedly for an empty element. It seems like a
stupid solution, but I couldn't figure out a more solid way; there's no React
callback for completed renders.

~~~
dandelany
Seems to me you could wrap ad elements in container components that have:

shouldComponentUpdate() { return false; }

Which would prevent React from re-rendering them after initial mount... any
reason why this doesn't work? I do this often when using d3 selections to keep
React out of the way and catch incoming props in componentWillReceiveProps
instead.

~~~
STRML
This is the right answer. This will effectively keep React from touching the
element ever again after the initial render.

~~~
talldan
I'm intrigued as to why you think this approach is better than using a key?
The 'shouldComponentUpdate' way of doing things means any changes to props or
state on the component have to be handled manually, which can introduce a lot
of non-trivial and overly complex code.

------
nulltype
I've been looking at reactive UI design, and it seems weird to me that
React.js has this React.createClass and .setState stuff. It seems like it
would be better to let the user manage the state and just re-render whenever
the state changes. Am I missing something about how this works that makes
those necessary?

~~~
Swizec
By making it explicit and a bit clunky, you discourage users from using state.

Without explicit functions to be called, you can't detect state changes and
would need polling. This is terrible.

At the end of the day, it's a limitation of JavaScript because unlike with
Python, for example, you can't have automagic getter/setter functions. They
_have to_ be called as functions.

~~~
nulltype
Seems like .observe() would fix that polling thing, right?

[http://www.html5rocks.com/en/tutorials/es7/observe/](http://www.html5rocks.com/en/tutorials/es7/observe/)

Also you could just re-render whenever any event happens, which is probably
when your state changes anyway.

~~~
lopatin
One reason for the explicit method may be that React does an internal
optimization where it batches state updates together. Two calls to setState
can result in just one render.

[https://groups.google.com/forum/#!msg/reactjs/R61kPjs-
yXE/ys...](https://groups.google.com/forum/#!msg/reactjs/R61kPjs-
yXE/ysmpC0IvA4YJ)

~~~
masklinn
No reason why this wouldn't be possible with Observe, the first call schedules
a re-render and the next one doesn't do anything since there's already a re-
render scheduled.

------
revskill
I've wrtitten a book to show how to integrate Rails with React.js. It uses
Backbone to act as Router. You can try it at
[https://www.gitbook.com/book/checkraiser/rails-and-react-
js/...](https://www.gitbook.com/book/checkraiser/rails-and-react-js/details)

------
perrywky
Suggestion: do not change any ui in any event handlers, otherwise you are
doing it wrong

