
Things every React.js beginner should know - Scriptor
https://camjackson.net/post/9-things-every-reactjs-beginner-should-know
======
marknutter
So here we see the culmination of the great Frameworks vs. Libraries divide.
Frameworks alleviate the need for the type of articles like the one linked
here because they eliminate choice paralysis and imposter syndrome. Everyone
is worried about whether or not they're doing things The Right Way™ and so
they either blaze ahead and hit the same pitfalls everyone else does (and then
write blog posts to warn others) or they hold off on adopting the tech until
they are shown The Right Way™ by someone else.

The truth is, libraries and frameworks both end up being equally complex to
work with, precisely because the _problem of building large applications is
inherently difficult_.

It all comes down to personal preference:

Are you the type of person who is more likely to believe you can do something
better than everyone else, or are you the type who is more likely to defer to
those you believe to be better than you?

Are you decisive or do you agonize over the smallest choices?

Do you feel a compelling need to understand how everything works, or are you
willing to implicitly trust other people's systems?

I find it amusing that people who gravitate toward smaller libraries like
Backbone.js and React.js rail against frameworks like Ember or Angular for
being overly complex, heavy, and "magical", and then proceed to cobble
together a Rube-Goldberg-esque system of disparate dependencies to achieve the
same goals. When React first started getting popular all you read about was
how simple the API was and how it was Easy to Reason About™. Fast forward to
today and you need to have working knowledge of WebPack, ES6, Redux,
immutable.js, Babel, and a bevy of other dependencies to be aligned with the
React ecosystem's ever-evolving best practices.

The exact same thing happened with Backbone.js and it will probably happen
again with the next shiny new view-model library to ride the hype train.

It's important that I point out, however, that none of this is necessarily a
bad thing. Smaller libraries like React.js and Backbone.js encourage a
cavalcade of innovation from which awesome things like Redux are born. But
let's not pretend that this doesn't result in a heckuva lot of churn for the
average developer whose job is to simply get shit done.

~~~
woah
You describe ES6 as some kind of exotic dependency. Actually once you get rid
of ES6, the only dependencies in your list are immutable.js which is optional,
and redux, which has become the well-known default.

~~~
marknutter
> You describe ES6 as some kind of exotic dependency.

To the non Silicon Valley / Hacker News crowd, it certainly is. And using ES6
means you need to make a choice about which transpiler to use, which build
tool to use, etc.

> Actually once you get rid of ES6, the only dependencies in your list are
> immutable.js which is optional, and redux, which has become the well-known
> default.

Well known to who, exactly? Because the "well known default" as of a few
months ago was Reflux, and before that it was Flux. Oh, and there's Relay and
GraphQL.

When's the "well known default" going to change again? I give it two months
before everyone rushes to the next new gotta-have dependency. It's like
reading Dr. Suess's The Sneetches.

~~~
daveidol
You're not wrong: things do change quickly in the JavaScript world. But have
you actually been following this stuff very closely?

"Flux" was never a "well-known default," because there was no single "Flux"
library - only Facebook's little written guide and an implementation of the
dispatcher (a small part of the overall Flux architecture).

So, there were about 500 different implementations of "Flux" \- none of which
I'd say were ever considered a "well-known default" (the biggest ones -
Reflux, Alt, Marty, Flummox, and Fluxxor - all have roughly between 1000 -
3000 stars on GitHub).

Then, Redux came on the scene and became the first and only "well-known
default". Several of the Flux libraries I just mentioned actually deprecated
themselves and put up notices to use Redux instead. As of the time of this
writing Redux has almost 13,000 stars on GitHub.

Relay/Falcor are really part of an entirely different thing than React; they
are about replacing the traditional REST API with an entirely new paradigm.

~~~
marknutter
> But have you actually been following this stuff very closely?

I have, but I'm trying to spin my comments from the perspective of the average
developer. People who are passively keeping tabs on what this whole "React"
thing is about are probably feeling a little uneasy about all the churn. I
agree that Redux has emerged as the clear solution for data management, and
I'm a huge fan. But I don't use it with React. I'm keeping my distance from
that ecosystem while the dust settles and waiting to see what kind of splash
Angular 2 makes.

> Relay/Falcor are really part of an entirely different thing than React; they
> are about replacing the traditional REST API with an entirely new paradigm.

But what app doesn't use a traditional REST API? Why _wouldn 't_ people want
to use the latest hotness to come out of Facebook™ or Netflix™? It's this kind
of uncertainty that keeps people off balance.

------
pkrumins
I'm not a React or Angular expert, but do you really put HTML inside of your
JS code? It just bothers me too much. We spent years in early web days
learning that code and templates should be separate, yet here we are putting
HTML inside of code, which goes against years of practice. Can anyone share
their professional thoughts about this?

~~~
matt4077
This is a debate that has been going on since I started in the late 90ies.

You need some sort of logic in your views, no matter what system you use, i.
e. loops or formatting dates.

Because people are raised on the "don't mix logic & layout" maxim, they feel
dirty when they write sich logic in their usual language.

.. so they invent template languages...

... that then expand to be turing-complete and basically offer everything
their primary language offered in the beginning.

So you end up with a new language to learn, which is usually clunky and ugly
just for the bragging rights of "not mixing logic & views". Which is
completely stupid. Views can (and almost always need) to contain some logic
and the best language for that is the one you're using everywhere else.

~~~
aikah
> ... that then expand to be turing-complete and basically offer everything
> their primary language offered in the beginning.

then they wrote template languages on top of the template language to separate
layout and logic again ( PHP vs Twig/Smarty )

so maybe we need to step back a little and figure out how to write a language
that wouldn't need a different syntax for logic and layout. This family of
languages exists already, but since current developers grew up with C like
languages, it is not that popular.

IMHO the best compromise is direct support for XML syntax inside languages
(which Javascript had at some point with E4X) because I don't think anyone
will be able to make developers use LISP like languages on a wide scale. JSX,
with some modifications and standardisation could also be a solution.

~~~
escherize
I'm a huge fan of Clojure's Hiccup library. It allows the user to make html
like the following.

Here's a function that always returns true - but it could do any kind of data
access. It is just plain Clojure.

    
    
        (defn selected? [] true)
    

Here is a datastructure that represents html:

    
    
        [:h2 {:class (when (selected?) "selected")} "Hello"]
    

Calling the function hiccup.core/html on that datastructure yeilds an html
string like this:

    
    
        "<h2 class='selected'>Hello</h2>"
    

So that's great for _strings_ right? But there is an awesome library for
ClojureScript called Reagent. And it uses those simple datastructures to
generate react components!! I put some more examples at:
[http://hiccup.space](http://hiccup.space)

~~~
munro
I love Clojure, but I'm tired of embedded DSLs, they're a dime a dozen. You
can argue the benefits of Hiccup's syntax & s-expr all day, but it's still a
different, and unpopular syntax for describing HTML.

The ability to copy snippets of HTML from web, or old code when refactoring,
or from Clojure/Hiccup to another language & framework, or changes from
developer tool, or familiarity for new engineers, or not having to care about
what flavor of HTML is hip today is a huge productivity boost for me.

I would love to see push for template strings [1] in Clojure, it should be
trivial with macros. It would only take some time for IDEs to catch up.
They're good. So good they've even influenced Python 3 to add them.

    
    
        (defui my-component [x]
          "<h2 class=(when (selected? x) ["selected"])>Hello</h2>")
    

[1] [https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/template_strings)

~~~
escherize
So you _actually_ use function names as strings? That seems like a problem,
and that it would need its own special editor tooling. Yikes.

~~~
munro

        (defui my-component [x]
          <h2 class=(when (selected? x) ["selected"])>Hello</h2>)
    

It's possible to macro the above to the code below, without any language
extensions. IntelliJ has powerful nested DSL introspection, it would be neat
if Cursive allowed to hook into this through defui's metadata for
highlighting. I was a hater of JSX until I used it. Now I hate eDSLs. :D

    
    
        (defn my-component [x]
          [:h2 {:class (when (selected? x) ["selected"])} "Hello"])

------
diggan
> 5\. Use Redux.js

Well, that is not really something every React.js beginner should know. Feels
weird to say that a X beginner should learn framework Y since he is probably
just interested in X...

> 6\. Always use propTypes

Worth mentioning that this slows down your application since React needs to
check all the props. Don't forget to set NODE_ENV=production when compiling
your production script.

~~~
awjr
If you are learning MVC, only learning V is not going to get you far.

I do wonder if things like Typescript can solve a lot of the speed issues.

~~~
EvanPlaice
Why would you assume Typescript solves any speed issues?

Typescript's type checking adds overhead just the same. So it's also a good
idea to disable checks during runtime.

~~~
tlrobinson
TypeScript doesn't do any runtime checks, AFAIK. In fact, that's one of their
stated goals: "Impose no runtime overhead on emitted programs."
[https://github.com/Microsoft/TypeScript/wiki/TypeScript-
Desi...](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals)

~~~
EvanPlaice
To-may-to, to-mah-to. That doesn't answer what I was asking.

Fact: type checking is disabled during runtime.

Why would one assume that Typescript somehow solves speed issues? It has no
measurable impact on runtime performance.

~~~
tlrobinson
I was addressing the second part of your comment. TypeScript is a static type
checker. It operates at compile time. There is nothing to "disable" at
runtime.

But yes, regarding your original question, you are correct, aggressive
optimization is a non-goal of TypeScript. It won't improve performance.

------
didgeoridoo
#10: This guide will be out of date in 3 months.

~~~
elcct
Good that with Google you can limit your search to a certain time frame.
Personally, when I Google stuff about React, I set filter to "Past month" so
that most results are quite up to date. I wonder if in the future the project
that you start doing in the morning will use outdated libs by the evening ;)

~~~
marknutter
Does this not seem like a problem to anybody else? Wasn't the whole point of
React that it was supposed to be simple? And yet things have gotten so complex
you're giving advice that anything older than 3 months isn't even worth
reading?

------
tptacek
Someone sell me on Webpack? We use Browserify for no other reason than that
someone gave me a boilerplate Gulpfile that relied on it.

What part of my life would actually get better if I took the 4 hours of my
life I will never get back to make this switch?

Thanks!

~~~
mbrock
You can run "webpack-dev-server", which uses your Webpack configuration to
serve your scripts with its own web server.

That means (1) it can do incremental recompilation, which I can't live without
since my build takes 20 seconds; and (2) it can block requests while
compiling, which is way better than having a background thing (e.g. watchify)
recompile your code, since it means you're never interacting with a stale (or
god forbid partial) compile.

The dev server also does automatic page reloading on recompile via some
injected script magic. In my case that means I often don't even need to alt-
tab to see my updates, like if I'm messing around with styling.

Webpack also has a whole paradigm that expands the use cases of require() in a
pretty interesting and useful way. For example, you can tell it that
require("../../icons/lolcat.png") should resolve to "static/lolcat.[8 chars of
base64 SHA-256].png" and also do the appropriate file copying. Or you might
want require("./stuff.csv") to resolve to a parsed JSON table, or any such
transformation. There are a bunch of plugins for common uses. It's common to
use require() even to load your CSS, because then Webpack can handle running
it through your auto-prefixer or whatever.

It might seem kind of bloated, and I love Browserify for its simplicity, but
I've come around to really like Webpack now that I've spent the proverbial 4
hours.

~~~
Lazare
FYI, browserify has support for all the cool tricks you list too now; it's
just a question of finding and wiring up all the right plugins.

Eg, lessify, css-modulesify, or csvify will handle the cool require tricks,
browserify-hmr does the fancy hot module replacement, watchify has incremental
recompiliation support if you manage to configure it _just_ right, etc.

Mind you, I find webpack easier to configure (all the fancy browserify plugins
destroy it's simplicity), but the two toolchains have had feature parity for a
while.

~~~
mbrock
Oh, I didn't know that, thanks.

------
Ronsenshi
#3 Write functional components

I'd say "Write functional components where it makes sense". For simple
components that is a reasonable advise, however in cases when you need such
methods as `componentDidUpdate` or generally any lifecycle methods - that
won't do and you have to use classes.

~~~
_asummers
Not a React guy, but why couldn't the component that updated broadcast that it
did so? Or is that componentDidUpdate method a callback to the message I'm
describing?

~~~
lopatin
Depends on what kind of component just updated. If it's a low level text
field, it probably shouldn't broadcast the change to anywhere else in the
program. Instead it would invoke it's 'onChange' callback. This way, there are
no extra dependencies for making the text field component work. The parent
component always provides the onChange callback and takes action accordingly.

However, if the component that just updated is high level, like an entire page
or something, then it's reasonable to assume it's a one-off controller
component and you should feel free to broadcast messages and couple the
component with other parts of the program.

[https://medium.com/@dan_abramov/smart-and-dumb-
components-7c...](https://medium.com/@dan_abramov/smart-and-dumb-
components-7ca2f9a7c7d0#.1na8fj54h)

------
jastanton
Fantastic article, in the past 9 months you've hit on nearly all of my
discoveries.

Something I do now every time I create a new react app is to create a base
class that extends React.Component that uses `PureRenderMixin`. When doing
this I can prevent unnecessary renders from props changes. A killer of this
would be passing an prop to a child that always changes its identity, like
passing a function that calls `bind`, Because bind create a new method every
time its call the identity always changes and the method will always be re-
rendered. Knowing gotchas like these can help really speed up apps!

------
k__
I tried a different approach here: [https://github.com/kay-is/react-from-
zero](https://github.com/kay-is/react-from-zero)

------
lukesan
What really bothers me about React (and other frameworks) that without JS you
do not see anything. No fallback. No progressive enhancement. Is this really
the way to go? Did JS replace HTML/CSS as the backbone of
websites/applications ?

~~~
andrewingram
This isn't strictly true. Though the workflow isn't ideal yet, it's perfectly
possible to build a React project which is initially rendered on the server
and then progressively enhanced. I've done it before, as have others.

In fact, my single biggest criteria for any tech I add to my stack is that it
doesn't get in the way of server-side rendering (the second biggest criteria
is that it doesn't add significant weight to the client-side JavaScript
payload).

~~~
lukesan
Sounds great. Do you know any good resources for building a react application
by progressive enhancement?

~~~
swah
Google "server side React rendering".

------
mythz
# 3. Write functional components

Functional Components don't get Redux's connect performance optimizations
which is a good reason to avoid them:
[https://github.com/rackt/redux/issues/1176#issuecomment-1670...](https://github.com/rackt/redux/issues/1176#issuecomment-167015145)

~~~
stickperson
I think Dan is making a different point. He's saying functional components are
just like regular components in terms of speed. The author of this article is
saying use functional components so it's clearer when a component needs to be
split up.

~~~
saidajigumi
I have to admit I find the author's insistence on defining a component as a
function to be a big red herring. Instead, it feels like the presence of JSX
outside of the component's render() method is the (potential) code smell.

It doesn't help that several popular React & React Native tutorials out there,
for understandable simplicity, opt to use "renderSubThing" methods. In the
examples and in my own code so far, I mostly find those sub-render methods to
be a proxy for "I don't want to break stride to make a new component, so I'll
jam this stuff in a method and refactor later." That's great, so long as the
refactor actually happens.

(Hm, that'd be a great candidate for a vim refactoring plugin...)

------
kieranajp
Google cache:
[http://webcache.googleusercontent.com/search?q=cache:https:/...](http://webcache.googleusercontent.com/search?q=cache:https://camjackson.net/post/9-things-
every-reactjs-beginner-should-know)

~~~
camjackson
Should be back up now!

~~~
darrhiggs
Hey, thanks for this.

With regards to redux-thunk, have you taken a look at redux-saga[0]? Any
thoughts?

[0] [https://github.com/yelouafi/redux-
saga](https://github.com/yelouafi/redux-saga)

~~~
camjackson
I've seen it mentioned by a few people, including Redux creator Dan Abramov
(who is very open about tweeting links to 'competing' libraries!), but I've
only taken a brief look so far.

My initial impression is that it seems really interesting, although I wonder
if the use of generators will scare people away. Many devs are already
exhausted with the number of new JavaScript features they're being told to
learn.

I definitely want to dig a bit deeper and try it out properly though.

~~~
acemarke
Best comparison I've seen so far is that it's sort of like "background
processing threads for Redux". The downside is that it might not mix well with
time-travel debugging, because a saga effectively has its own internal state.

That said, Dan Abramov does seem to think it's a very intriguing approach, so
it's worth keeping an eye on.

------
tzaman
I'v done an integration test example (no PhantomJS, just jsdom) if anyone is
interested:
[https://gist.github.com/tomazzaman/790bc607eb7ca3fd347f](https://gist.github.com/tomazzaman/790bc607eb7ca3fd347f)

------
todd3834
Great article! As we have been on-boarding developers with React, we noticed
that all of the boilerplate needed to get Babel, Webpack, Redux, and a testing
environment (we use Mocha, Karma, and Chai) was simply too much for most
people to handle while beginning something new. There are lots of boilerplate
projects but telling someone new to fork a project on GitHub and start
building an app from there was raising some eyebrows as well.

That's not all, there are really amazing developer tools available for React
development like the redux dev tools, and hot module replacement to name a
couple. These tools are extremely helpful to beginners but a beginner is not
going to enjoy the extra work of setting that up as well.

Imagine if you were going to build an app with Rails and the instructions were
to follow a tutorial that had you manually hook up active record, create your
bootstrap files by hand, write your own code to rebuild the server ever time
code changed… or even forking a boilerplate Rails project and going from
there. I don't believe Rails would have become what it is today without the
Rails CLI.

What happens when the boilerplate changes? What if you find a XSS
vulnerability in the boilerplate project that you used in your last 10
projects. Rails developers have identified and quickly patched several
security vulnerabilities over the years. It's usually as easy as updating a
gem file to patch your app. With the boilerplate approach, you would have to
manually update all of your apps or try to merge the update from the project
your forked. That isn't going to be fun at all.

Finally, one of the coolest things you can do with React is server side
rendering to build universal apps. At this point, even if you know exactly
what you are doing, setting up a new app is going to give you way too much
work just to get started. So you'll need to find a boilerplate with server
side rendering and fork it. There are way more opportunities for security
issues when you increased the surface area of your app's responsibilities.
There will be updates to this boilerplate and you will have to merge them into
all of your apps. I hope you like manually updating files and resolving merge
conflicts on files you don't really understand…

We set out to resolve these problems when we built GlueStick
([https://github.com/TrueCar/gluestick/](https://github.com/TrueCar/gluestick/)).
It's a CLI that allows you to quickly generate new apps using all of the tools
we like to use on React applications. You have generators for creating
containers (smart components hooked up to redux), components, and reducers.
Redux is set up out of the box. You have server side rendering out of the box.
We also push as much of the boiler plate code into the GlueStick module as we
can. This lets you easily get performace and security updates as well as new
features by simply updating the node module. You also get a sane folder
structure so that all of your apps built with this tool will be easy to
navigate.

We built this tool at TrueCar but we open sourced it. That means you can take
it and make it your own, contribute back if you want to improve it and you can
rest assured that it is backed by a big company that is heavily invested in
seeing it succeed.

~~~
Reedx
Nice, I like this a lot. I think it's the cleanest and most concise approach
I've seen re: universal React/Redux.

Is there a way to override or extend the webpack config though? (without
having to fork it) What if some projects need different loaders or want to use
code splitting, etc?

~~~
todd3834
We have plans to implement this. I don't think it will be too hard to
implement. The hard part will be coming up with a clean approach for
developers as they build apps. It is on the list of things we would like to
add. A PR for this would be greatly appreciated :)

------
ktdrv
Some very good advice here but after reading through the list I had a familiar
feeling. Functional, stateless, typed, Redux? Yep, that's Elm.

~~~
meat_fist
From what I can tell, the only reason to use React/Redux over Elm is to have a
more popular resume. This is not a criticism, just an observation.

------
Keats
Good advices but I would add TypeScript as well

------
joseraul
How about TypeScript/TSX? React's components and "views" are easy to type (and
you get completion in your IDE) but I still have to find a convenient way to
type an Immutable map where each key/value pair has a different type (the
equivalent of a TypeScript object). Any idea?

~~~
Retozi
you can use the functional way of setState by passing a transaction function
(state: State) => State . This allows for typed, immutable updates since the
function gets passed a copy of the state.

If you need an object (say to use it in something like Redux), you have to
write a wrapper like so:
[https://gist.github.com/ebi/d186c4297c84d562aeae](https://gist.github.com/ebi/d186c4297c84d562aeae)

------
baby
``` <section> <div><h1>Latest posts</h1></div> ```

isn't that div unnecessary?

~~~
camjackson
In the example as given, yes. In reality, it has `className="row"`. I stripped
out all of the classes from the example code to make it easier to read.

