
Khan Academy's React style guide - mdp
https://github.com/Khan/style-guides/blob/master/style/react.md
======
unoti
I've been working on learning React, and finding it particularly difficult. It
appears there are a large number of things I need to have in place and pieces
of knowledge I need before I can use it. These include some kind of Js
compilation step like Webpack or Browserfy, something like Babel, a knowledge
of how to use ES6, an understanding of React, and an understanding of how to
use React-Router.

Although I've done some Javascript on the front end, I haven't done the other
things I mentioned. The tutorials all seem to assume I know how to do
everything but one little piece of detail, and I'm finding it difficult to
bite on the elephant. It's hard to tell where to start on learning this stuff,
and how much I need to learn before I can use it.

Any suggestions for what resources and approach to use to learn react? My goal
eventually is an app that runs in 3 versions: web, iOS, android. I don't
intend to use javascript on the server.

~~~
dominotw
>and an understanding of how to use React-Router.

Gosh no. You don't need react router for simple applications.

~~~
unoti
When someone is looking at something in the app, I need them to be able to
paste a link to someone else, and have the recipient see the same thing.
Sounds like a job for react-router, right?

~~~
dominotw
you can use history api or many of the simple abstractions like page.js.

react-router is waay to complicated for trying to do everything in a
declarative way.

------
andreasklinger
Request for comment:

Linters are by far powerful enough by now.

Can we (as community) switch to documenting style guides as linter rulesets +
custom linters. Eg for javascript: eslint and jscs

Written style guides are good for understanding why - but linters actually
help others to adapt to it quicker

~~~
greg5green
AirBnB has a similar style guide for React and has a linter file for eslint
with the React plugin. Works pretty well.

I'd like to see more style guides come with similar set ups.

~~~
pbreit
Is it available?

~~~
themichaellai
Yes:
[https://github.com/airbnb/javascript](https://github.com/airbnb/javascript)

~~~
bronson
or `npm install --save-dev eslint-config-airbnb`

------
iamjs
It's probably a good time to start looking at using the Fetch API [1] for
making AJAX requests instead of using jQuery or Backbone (or even
XMLHttpRequest). Support seems to be growing quickly and Github's polyfill [2]
can help cover the gaps.

[1] [https://developer.mozilla.org/en-
US/docs/Web/API/Fetch_API](https://developer.mozilla.org/en-
US/docs/Web/API/Fetch_API) [2]
[https://github.com/github/fetch](https://github.com/github/fetch)

~~~
tracker1
Agreed... I really have come to like fetch, though I usually wrap it in a
couple functions for my most common use cases... since some of the options are
a little tedious to specify over and over again... such as `postJson(url,
data)` which will post the data as json, and resolve the json response with
some extra error handling.

It works well, and combined with babel for async/await, the workflow is pretty
smooth as well.

------
tzury
John Resig (jQuery creator) is one of the chief architects at there, and yet
you see, this line:

    
    
        Never use jQuery for DOM manipulation
    

Nice.

~~~
doppel
I think the implication is not that jQuery is bad for DOM manipulation, but
that you should leave DOM manipulation to React to have a 1:1 relation between
the held state in React and the actual DOM. In other words: Do not manipulate
the DOM outside of React.

------
pramodliv1
A couple of questions:

>Do not use Backbone models

I use Backbone models for ajax since it makes decisions such as PUT vs POST
and model.save() looks cleaner than $.ajax. Also, Backbone collections provide
a declarative way to handle sorting and duplicate models. But these models are
internal to the Store and not exposed to the views. I'm still a React newbie.
Is this a valid reason to continue using Backbone?

2\. It seems as though Khan Academy do not use React for SVG elements in their
interactive exercises. For example,
[https://www.khanacademy.org/math/geometry/transformations/hs...](https://www.khanacademy.org/math/geometry/transformations/hs-
geo-reflections/e/defining-reflections) Do you plan to migrate SVG to React?

~~~
ariabuckles
1\. If you're not passing the backbone models to React components, this sounds
fine. backbone models as props ends up being really painful because of how
mutable they are, and when we tried to manage that with mixins, it was buggy
and caused problems (note: I'm not familiar with the actual mixin we used
there and whether there was a better way to do it). Since most flux
implementations are pretty stateful/mutable themselves, using mutable backbone
models there, _so long as you copy data out to pass to react views_ , seems
safe. Though I'm excited long-term about the immutable flux implementations
([https://github.com/rackt/redux](https://github.com/rackt/redux))

2\. We had a library originally written by Ben Alpert (now core react team)
that handles all of our interactive svgs [1]. Since KA has a lot of legacy
code there, and there hasn't been an immediate benefit to porting it (which
would take a pretty significant time investment, on the [very roughly] order
of a couple dev-months), this is still mutable jQuery/raphael code. There have
been a lot of talks of eventually porting this to react, but the immediate
need for it hasn't been there yet. However, I did write a React wrapper around
much of this code which is used by newer interactive widgets [2].

[1]: [https://github.com/Khan/khan-
exercises/blob/master/utils/gra...](https://github.com/Khan/khan-
exercises/blob/master/utils/graphie.js)

[2]:
[https://github.com/Khan/perseus/blob/master/src/components/g...](https://github.com/Khan/perseus/blob/master/src/components/graphie.jsx)

~~~
pramodliv1
Thanks! I did not about Redux and the React wrapper.

------
cnp
I'm curious why the top is preferred over the bottom:

Open elements on the same line.

The 80-character line limit is a bit tight, so we opt to conserve the extra 4.

Yes:

    
    
      return <div>
        ...
      </div>;
    

No:

    
    
      // "div" is not on the same line as "return"
      return ( 
        <div>
          ...
        </div>
      );
    

The latter I feel is much more readable and clear than the former, as it has a
certain symmetry and cohesion that you find in normal html. The top one seems
to be break readability. Wondering if anyone can comment on this specific
decision?

~~~
xanderjanz
Their logic is that because elements are typically deeply nested, it's better
to sacrifice the readability for the saved indentation. By the time you get 4
child elements deep, almost half your line space goes to tabs.

------
traviswingo
I find it funny seeing this section:

[https://github.com/Khan/style-
guides/blob/master/style/react...](https://github.com/Khan/style-
guides/blob/master/style/react.md#minimize-use-of-jquery)

Even though John Resig is one of their main devs.

~~~
mikegirouard
I thought so too. I guess this is a good time to remind ourselves that we are
not our work and it's best not to be too attached to the things we create.

It's worth noting however that the heading says to minimize jQuery and more
specifically jQuery plugins. My guess is that jQuery is fine as long as it's
serving a low-level function (XHR, etc).

~~~
tracker1
Not sure how much I agree there... I think the goal is to get away from
kitchen sink libraries, react's rendering flow allows for an interaction style
that doesn't typically need something like jQuery...

For that matter, I'm surprised they don't have standard polyfills that include
fetch, which combined with babel (async/await ftw) make your workflows much
easier to reason with.

------
aaronkrolik
Style question re dom manipulation: third party embeds, such as twitter,
instagram often come as specially classed blockquote elements that are swapped
with iframes by a jquery plugin. What is the best way to integrate this with
react?

------
codingdave
"Fit them all on the same line if you can." (HTML Properties) -- OK, easy
enough, my editor has no limit on its line length. I can always fit them on
one line. Or did they expect it to fit on one line visually. If so, at what
width to they expect my editor window to be?

In all seriousness, though, I appreciate the brevity of this guide. It can be
quickly read and understood, and is not the fully-fledged book I've seen from
other places.

~~~
techterrier
80 characters

~~~
codingdave
Yes, the "In all seriousness" phrase was intended to let you know I was
joking. I knew what they meant, even if they didn't explicitly say it on that
line.

~~~
teh_klev
Does actually mention the 80 character line length limit at the top of the
article, just under the TOC:

>" _Follow the normal JavaScript style guide - including the 80 character line
limit. In addition, there are several React-specific rules. "_

------
liquidise
A number of these guidelines reinforce my biggest complaint with React: it is
architecturally difficult to avoid monolithic view files.

In a traditional web app, we have 4 layers: client views, client app, server
app, database. React, described as a strict view layer, in reality is being
used as much more. At this point, it is not just consuming the client app, but
is also taking nibbles at the server app as well.

To each their own of course, but i would ask people to hesitate about these
decisions. The architectural issues with monolithic views is well known, and
just because we have a shiny new tool does not mean we should throw that
understanding by the wayside.

 _Source: i work full-time on a React and Backbone app_

~~~
smrq
Can you explain what you mean a bit more? My experience with React is that
composing components is so trivial (particularly compared to e.g. Angular
directives) that I've tended to end up with very small view files (~10 lines
of DOM max, plus whatever functionality is directly tied to that). It's seemed
like one of React's greatest strengths to me, so I'm curious as to where your
complaint stems from.

(I don't use React in my day job... yet. But I'm considering pushing for it,
so getting a better understanding of its shortcomings is really important to
me.)

~~~
matchu
I think it might be an objection to what the style guide refers to as "logic
components": components that use React's `setState` to handle interactions and
decide what props to forward to a "presentation component".

Personally, I feel that React is a handy tool for both of these use cases, but
the fact that we're finding these two distinct types of components suggests to
me that React's "component" abstraction might be doing too much.

Maybe if we break React into the pieces that are helpful for "logic" and the
pieces that are helpful for "presentation" we'll end up with two abstractions
that are each better suited to their task.

React's ideology is still very young, so I'm hopeful that the community will
start to head in this direction, and I'm super excited to see how this plays
out :)

~~~
troybetz
Don't quote me on this, but I believe that's _exactly_ the rationale behind
the 'stateless functional components' introduced in 0.14.

[http://facebook.github.io/react/blog/2015/10/07/react-v0.14....](http://facebook.github.io/react/blog/2015/10/07/react-v0.14.html#stateless-
functional-components)

~~~
matchu
Yeah, I really dig those :D The concept of a "presentation component" has the
exact same semantics as a pure function, so I'm excited that we're actually
gonna get that abstraction.

The part that concerns me, though, is the logic component. Hierarchical
state/event management seems like a hard problem, and React does it okay, but
a lot of things end up coupled together: why does a component that manages a
state hierarchy and event flow need to be coupled to the idea of rendering a
virtual DOM tree? Can't I just declare that my TodoApp state is a composition
of my TodoList state and TodoForm state without _also_ declaring how I'll
eventually render them?

I wonder if anyone's come up with a really great abstraction for this yet that
checks all the boxes. I like the _philosophy_ behind how Redux manages state,
but React provides clearer encapsulation of state and doesn't make parent
components think about the events that their children are handling.

Redux is even crazy younger than React, though, so there's still plenty of
room to grow there, too!

------
twsted
"Do not use Backbone models."

This seems a little strong. What is the reason for this guideline? I know of
many projects that are combining the use of React with Backbone.

~~~
greg5green

      We are trying to remove Backbone from our codebase entirely.
    

This is more of a guideline for their particular organization -- they've
decided to move away from Backbone and don't want developers adding any new
Backbone code.

~~~
ariabuckles
Correct. That and passing mutable backbone models as props went poorly back
when we did more of that. Mutable props are hard to reason about and go
against all of the recommendations for React props. (There are plenty of good
use-cases of backbone out there though.)

------
amelius
It makes me feel so sad that the "state of the art" in front-end development
is apparently rerunning your render code on every little update. Yes, I know
there are shortcuts to making this more efficient, but in essence the
technique remains inelegant in the sense that it does not extend well to other
parts of the code (that runs computations that might also partially, and not
fully, change on an update).

~~~
enginous
This pattern of the virtual DOM has some parallels with functional
programming. At first look, using functional programming it looks like you're
sacrificing the performance that you gain from mutations -- which to some
extent is true. But when you look deeper, you'll find that the data structures
for functional programming languages have been adapted to work in a very
performant way with functional programming patterns.

In the same way, when you look closer at the virtual DOM model, you'll find
that you can optimize the usage very well. For example, when you use React
with immutable data structures (e.g., Immutable JS), deep equality comparisons
can be done very quickly to reduce renders to the minimum subtree required,
and to issue the renders for a given change in a batch operation.

With React, you often end up with even faster code than using manual DOM
manipulations. Of course, your performance will vary depending on how you
implement your code. Depending on which model you're using, and how you
program, you may end up with a faster or slower product with either
methodology.

But at the end of the day, the performance gain from running code using state
mutations just doesn't seem worth the effort of having a significantly harder
time reasoning about the code, and having to deal with the challenges of
scaling a project where the complexity grows much faster with each line of
logic.

And my feeling is that due to the time invested in managing a more complex
project that deals with mutations, the "performance per engineering hour"
gained for projects using a virtual DOM is more favorable for many projects.

~~~
amelius
I think the main problem with your argument is that you assume that the world
looks like a shallow tree. For UIs this may be, to a great extent, true. But
for non-frontend code, the world looks more like a deep DAG (directed acyclic
graph).

Also, suppose I have a list of thousands of elements. Now suppose one element
is added to the list. React will still perform a comparison operation on all
of those thousands of elements.

~~~
pramodliv1
>> React will still perform a comparison operation on all of those thousands
of elements.

Using the `shouldComponentUpdate` API alleviates the problem, doesn't it?
[https://facebook.github.io/react/docs/component-
specs.html#u...](https://facebook.github.io/react/docs/component-
specs.html#updating-shouldcomponentupdate)

~~~
epmatsw
Eh, kind of. If you're rendering, for example, a Table with a lot of TableRows
and change one of the values in the data array being passed to Table.props,
you'd return true from Table.shouldComponentUpdate, and then each child
TableRow would need to run its shouldComponentUpdate, even though only a
single one really needs to update. So the argument is GP is making is that
it's more efficient to directly update that single DOM element rather than
update the data and then perform the calculations to determine that we need to
update that single DOM element.

~~~
bryanlarsen
True in theory, but as long as each TableRow implements the PureRenderMixin
and the Table render itself is efficient, you're going to need a lot more than
a thousand rows before React has any trouble hitting 60fps in my experience.

But if you can't meet both those conditions, that sort of thing definitely can
get quite slow.

------
lalwanivikas
React and Khan Academy reminded me of this funny tweet by one of their
developers:
[https://twitter.com/jdan/status/655432901782302720](https://twitter.com/jdan/status/655432901782302720)

------
NoCulturalFit
I would love to read more about styling inline and completely remove external
CSS files.

Are there any CSS-frameworks that have been converted to JS but not are not
their own components yet? It's easy to find React-Bootstrap but that comes
with ready made components, I am looking for styling that's purely in JS so I
can make my own components.

Also would a route-component be considered logic or presentation, or maybe it
is its own thing and they forgot to mention it?

~~~
drhayes9
I don't like inlining styles as objects in React so I went looking for a
solution that would work with the toolchain I'm using for my current project.

I'm working on a project now that is using a combination of react-css-modules,
webpack, and an ExtractText plugin for webpack that means each React component
I write can have an associated CSS file.

Each class in the CSS file gets mangled so that it doesn't affect things
globally by react-css-modules. Then the ExtractText plugin for webpack pulls
all those CSS files out into one, global styles.css file.

Ultimately, that means that my CSS file might actually, over the life of the
project, shrink! Unheard of.

In the same project I'm using redux and redux-router. The router consists of
declarative components, like "<ReduxRouter />" and "<Route />".

