Hacker News new | comments | ask | show | jobs | submit login
Thinking in React (facebook.github.io)
250 points by AJAlabs on May 27, 2016 | hide | past | web | favorite | 52 comments

FWIW, this has been in the React documents from near the beginning:


I've frequently referred to it when I need to refresh my memory on how to start in React from scratch.

This has been one of the recommended readings for our workshop students for quite some time: https://reactweekend.eventbrite.com

We also recommend the following:

9 things every React beginner should know. Take it with a grain of salt, but it's a good intro to some common React best practices. https://camjackson.net/post/9-things-every-reactjs-beginner-...

ES6 Guide. A nice resource for anyone new to ES6. Only sections 1-5 recommended. https://mrzepinski.gitbooks.io/es6-guide/content/

Edit: add additional recommendations.

I was surprised too and checked if there was something new.

This is how I met and learned react in the first place and inspired my first react project, http://hasgluten.com

Yea when I started reading the introduction I was like 'wait, that sounds familiar'...

Yeah, surprised that is just getting posted for the first time here.

No, this is the second time this page was posted, according to https://hn.algolia.com/?q=Thinking+in+React. The page was first posted 2 years and 1 month ago in https://news.ycombinator.com/item?id=7672379, though that submission had only 6 points and no comments.

This is a very useful walkthrough.

Some links for those who are also interested in "Thinking in React" in a more conceptual way (#4 is a presentation from the same person who wrote the walkthrough):

1) React — Basic Theoretical Concepts: “A description of the conceptual model of React without implementation burden.” https://github.com/reactjs/react-basic

2) Pure UI: “A lot has been written about the merits of React as a framework. Today I’m compelled to write about the benefits of a programming model it enables and its implications to the design and creation workflow." http://rauchg.com/2015/pure-ui/

3) Removing User Interface Complexity, or Why React is Awesome: “I’m mostly concerned with the core problems of data binding and componentizing UIs. After much research and usage of the technologies mentioned above, I found React to provide the best solution.” http://jlongster.com/Removing-User-Interface-Complexity,-or-...

4) Pete Hunt: React: Rethinking best practices (youtube): “building views with JavaScript, ‘re-​rendering’ your entire application when your data changes, and a lightweight implementation of the DOM and events.” https://www.youtube.com/watch?v=x7cQ3mrcKaY

5) Nothing new in React and Flux except one thing: “What is it that makes React so innovative and compelling?… The Virtual DOM allows us to convert a mutable retained mode graphics API to an immutable functional immediate mode API.” http://staltz.com/nothing-new-in-react-and-flux-except-one-t...

(I collected them to go along with something I wrote in the same vein: https://medium.com/@firasd/interface-from-data-using-react-t...)

#4 is really my favorite. I know a lot of people who were hardcore opposed to React until they watched that presentation.

> React — Basic Theoretical Concepts


Let's just say, save this one for last.

Yeah. When looking for videos I saw he updated his presentation and gave it again, but there’s raw appeal in that first ‘Rethinking best practices’ talk. Just something coming in out of left field. (Another early presentation: “Tom Occhino and Jordan Walke: JS Apps at Facebook” https://www.youtube.com/watch?v=GW0rj4sNH2w)

Re: basic concepts, I admit my eyes glaze over by the time I read the heading “Memoization”. Opens with this great sentence though—I like to say ‘view as a function of state’, but he breaks it down even simpler—“The core premise for React is that UIs are simply a projection of data into a different form of data.”

I don't know much JS, let alone React, but after reading the OP link, "Basic Theoretical Concepts" made sense to me. The bit of Haskell experience I have probably helped.

I'm just amazed at how something that would appear to be so simple could be so complicated.

What do you mean?

I have little trouble building decent, dynamic web sites in python. When went through the article I was mostly befuddled.

Sorry about that. Anything in particular we could improve?

Add a glossary/dictionary for all the new React terms, at the end of the article ..

For folks just a little further into React, there's a great project called Storybook[1] which lets you put your JSON and React components, individually, into a really nice UI to try them out. Earlier HN discussion[2].

[1] https://github.com/kadirahq/react-storybook

[2] https://news.ycombinator.com/item?id=11411020

I know it's just a demo and I'm sure it scales very well, but I can't help but think that's a lot of code for a such simple UI. The intercoolerjs equivalent is pretty simple:


Don't misunderstand me, there are a lot of places where react is appropriate and intercooler isn't, but for something like this...

This is one thing I find a little bit frustrating with the tutorials of various JS tools. They fail to accurately describe a problem that they solve.

Usually you just get a quick paragraph going on about what you can do with the tool, then a quick example of something you could have easily done without the tool, then straight into the full API documentation.

And after I've read all that I'm still saying "Ok, that's kind of cool. But why would I add another dependency to my project when I can code your example up in clean, vanilla JS (or more often in these days, plain old React)".

I'd love to start seeing tutorial documentation address this more. Having a basic example is great, but it shouldn't be the only example. You should follow it up with a more complex example that really captures the reason you built the tool in the first place.

> This is one thing I find a little bit frustrating with the tutorials of various JS tools. They fail to accurately describe a problem that they solve.

Yes, this is valid for anything. It's harder to understand the solution if we haven't met the problem. For example, I realized the need of React after my template-based app was becoming a huge mess.

The intercooler.js example seems to be iterating over the results, building up a string of <tr> items, and then appending the string to the DOM?

Yeah, React is for stuff where you never want to do that... it's for when you write your table rendering stuff once, and then just change/update the data.

React also holds the entire UI state as data, things like: what information is typed in the text box, when to clear the text box, whether the checkbox is checked. The intercooler.js example seems to have a technique for showing a processing indicator based on an ID, so their approach to this kinda thing seems to be more 'implicit'. React doesn't have any UI-level abstractions like that, so you do have to implement things like that yourself. (Edit: I looked at the intercooler homepage and it's a specialized AJAX library, which explains what's going on in their example.)

Right, totally understand, but, functionally, these are pretty much the same UX (and a pretty common one).

My point is that this is quite a bit of code for the same UI and, unless there is a compelling reason to have a client side model (which, of course, introduces the complexities of syncing w/ a server side model/data store) then you end up with a lot of complexity for very little benefit.

Yeah, fair point. I would say, besides interacting with server-side updates, the other use case for something like React is when you have a bunch of event listeners and find they're getting out of control (onclick function triggering something else which has a condition to check the class attribute of something else etc.)

Is React worth it? How complex does your site need to be before it becomes worthwhile?

I've only played with react wrapped in reagent (cljs), but seeing the underlying code here, I feel comfortable saying you can benefit from this pattern relatively early. Just having the virtual dom/view-as-projection-of-state concept saves you a lot of mental overhead about state management. If you're going to build an SPA and you're not already totally sold on yourFavoriteJSFramework, give react a try.

I've actually found working with react/reagent to be substantially simpler to reason about, and lower complexity pays dividends far before any performance or scalability gains do (though I hear react is quite good in that respect as well).

For those of us who don't know it yet: SPA == Single page (web) application [0]

[0] https://en.m.wikipedia.org/wiki/Single-page_application

React is pretty easy to start with, for me the question is when does redux and the madness in redux starter kit become worth it.

Has anyone done anything non-trivial with [MobX](https://github.com/mobxjs/mobx) as an alternative to redux/flux with react?

I'm curious how that ends up working out. It is intriguing and enticing to me, because I have had similar experiences that the most 'challenging' part of using react is the flux part not the actual react part. But I'm just a react newbie, and based on my experience so far, am scared to go 'off the common path' at all because it tends to end up being a royal mess for reasons I didn't have the experience to predict in advance. :)

I faced this same question on a recent small project. For anyone dipping their toes into React, it's a huge leap of complexity. I thought I could jump into Flux just like React: get familiar with the concepts, do a tutorial or two, and start building. Nope.

I looked into Redux, but quickly realized it was overkill for my simple project. I eventually settled on Reflux, and I would highly recommend it for those who are just getting started with Flux.

Yeah, I can see the value in redux for a big app with lots of complex state to manage (eg Facebook), but it seems like major overkill in a lot of smaller apps where people seem to be reaching for it by default for some reason. Plain React components and a few helper modules can get you a surprisingly long way--there's really no need for more framework until deeply nested components make simple argument passing unweildy.

I saw this from Redux's creator that aligns with my take: "When people say setState() is an anti-pattern, they mean 500-line components with a complex setState() soup scattered across event handlers. When you spend your days looking for bugs in those handlers and moving them up and down component hierarchy, consider extracting it." https://twitter.com/dan_abramov/status/725090047557558272

I had that whole 'moving values and events up and down the component hierarchy, driving me nuts' thing going on when I tried to make an editor page for a two-level list. I added Redux and now I just directly read/update the list in the store from every component in the editor.

If what you have is a "site" (e.g. online newspaper, blog, brochure-ware etc.) don't bother.

If it's a web app, though, consider it, if you have lots of forms, controls, changing parts etc. (If you only have a few simple forms, e.g. a shopping cart + "buy" buttons, you won't really need it either).

Reusability is React's real value prop IMO. Other libraries and frameworks may give you the illusion of good encapsulation and composeablity but in reality it breaks down once something changes.

If you have a lot of same or similar views in your app used in different contexts then React becomes worth it really quickly.

React is worthwhile no matter how small it is.

Flux/Redux is the question. Thinking in those is much more difficult.

I'd love to hear what things you find complicated. I hear you though. Vue has a great abstraction. Although it does too much magic and quite slow at times.


for people who want to look into react itself without webpack, es2015 etc.

I'm a dab jQuery hand and I absolutely love the idea of React - reminds me of the best parts of XSLT. I'm struggling a bit with the pre-required tooling - not that it's there, but I'm just out of date with what a Babel is, what ESX is, how do I get Javascript 1.7 rendering in the browser, etc etc etc.

Is there a simple guide to that?

You would need some familiarity with npm first but after that the current practice is to use webpack with 'loaders' to transform JSX, ES6 etc.

This is intermediate: webpack-howto https://github.com/petehunt/webpack-howto

A simple starter for webpack: https://github.com/HenrikJoreteg/hjs-webpack

A simple guide? Sadly not, because the ecosystem around JS today is ludicrously over-complicated and changes so fast (and not always for the better) that any guide that wasn't maintained almost daily would be out-of-date within a few weeks at most. Fortunately, Babel[1] is actually one of the few relatively sane areas, and if you combine it with a couple of other tools, you can get most of the benefits of the modern tools while avoiding almost all of the crazy complexity and instability that plagues the ecosystem at the moment. I hesitate to continue with what will probably become quite a long post that dates just as fast here on HN, but since no-one else seems to have answered your implied question yet, here goes...

So, what is Babel? The short version is that recent versions of JavaScript (ES6 aka ES2016, and more recently ES7) offer some very nice new features. Unfortunately, they aren't universally supported in browsers yet, so you can't just use those features in .js files loaded from your pages. What you can do is mechanically translate your future JS code into today's JS that will run in browsers just fine[2].

Babel is a tool that does that translation. It's so much better than anything else that was around that for once pretty much the whole community does use the same tool for that job. It is also both well-documented (see the home page linked below) and reasonably transparent in what it does (you can look at its output and usually see clearly how it's converted any future language features in the input into code that uses only the features supported in browsers today).

As a bonus, in addition to translating future JS code into today's JS, Babel can also translate JSX code into today's JS at the same time. JSX is an HTML-like mark-up language that you can use to make working with React more convenient, but ultimately it's just nice syntactic sugar for some underlying ordinary JS (and as such it's completely optional, though in my experience almost everyone who works with React does use it because it's much neater than writing out the underlying JS manually all the time).

As I said before, there is plenty of ludicrously over-complicated tooling around for JS today, but you absolutely do not need most of it to be productive with the best tools. You can run Babel to translate a new-code JS file into a browser-compatible old-code JS file with a simple CLI command if you want. However, if you're looking to do modern front-end JS development work, I would suggest that there are two other tools you should become familiar with sooner rather than later.

First, if you're going to use almost anything in the modern JS ecosystem, you will probably want to install Node on your development machine. Node lets you run JS as a scripting language more like Python or Ruby instead of in-browser. Many of the modern JS ecosystem tools are themselves written in JS and run under Node, so it's necessary if you want to use any of those. Its accompanying package manager, NPM, also lets you install many useful things from a centralised source with a single command, including everything else I'm talking about in this post.

Second, if you're building projects of any significant scale, you'll probably want to divide your JS code into modules, and combine them together with proper respect for dependencies between them to produce the actual .js file(s) you'll use in production, much as you would in almost any other programming language. There were a couple of common ways of doing that historically, but they're now giving way to standardised language features that are part of ES6/ES2015. There are a variety of tools for doing this combination and dependency resolution, some much simpler than others. A sensible place to start is Browserify, which is widely used and simple-but-effective. Again, running this is a one-liner at a command line, and it plays nicely out of the box with any JS packages you install with NPM.

Finally, you have Babel itself to complete the trio. If you decide to work with Browserify, you may find it convenient to replace vanilla Babel with Babelify in your tool set. Babelify is essentially Babel wrapped up as a plug-in that integrates neatly with Browserify, which means you can run everything together with a single command, instead of manually transforming all your source files with Babel first and then running Browserify as a separate step to combine them.

With those tools, you can write almost anything you might want with the modern JS language features, easily fetch and include almost any modern JS library in your projects, and then combine everything with a quick command into a single .js file that you can include in your web pages as normal. Although these tools are much simpler than some you'll probably encounter, they are actually some of the best things out there, and for many projects they'll be perfectly sufficient even to generate production code for real sites. Once you're more familiar with the possibilities, you will probably want to explore other tools as well, but please don't let anyone tell you that you "must" have a task runner like Gulp or Grunt or that it's "best practice" to use a heavyweight bundling tool like Webpack. These claims are never universally true, IMHO, and they certainly aren't true while you're first trying to navigate the brave new world of modern front-end JS development.

[1] https://babeljs.io/

[2] There are a few exceptions that really do need built-in support from the browser that isn't there yet. Neither Babel nor any other tool or polyfill can help with those.

Apologies, I had a typo in there that I can't edit now. In case of confusion, the versions known as ES6 and ES2015 are the same thing, and likewise for ES7 and ES2016.

Not an experienced frontend developer per se, each time trying to study React it seems daunting, will things like vue.js a better method for 90% of the problems?

Angularjs is also complicated, if not more than React, especially it's now more like C# (typescript etc) which I don't like.

Maybe I'm just too dumb, or things move so fast and getting so complicated and I just can not catch up.

I will try to use jQuery and possibly vue.js for now, for the sake of KISS.

The Yelp clone was scary, yes, but this is pleasant. I'll try this when I get back home today.

It this very old or this is a re-write? I remember reading that a year or two ago.

Source[1] hasn't been updated in over a month, so it's just a repost.

[1] https://github.com/facebook/react/blob/master/docs/docs/thin...

The problem I've had developing with React (I've just done a little, I'm still a beginner), is it sometimes seems like a minor change to the UI can require a major change to the source, cascading through multiple components.

I think maybe this is reflected in this guide, such as the advice in the "Identify where your state should live" section (which they say is "often the most challenging part for newcomers to understand", which matches my experience), which suggests you should be looking at every single component involved and how they all relate to determine where the state should live.

This is very different from my previous (mostly OO, lately ruby) experience, where you really want to look at a component (in the broad sense, not neccesarily a view-layer, I just mean any object or 'piece') in strict isolation, identify what it's inputs and outputs need to be, and from that alone, in isolation, you know what it's API should be. And from this technique, you hope to wind up with components that that do not assume or depend on too much about their context of use and can be re-used and re-mixed in different ways without a rewrite.

I've found I've had to change my whole approach designing React -- when using my previous time-tested techniques, I would wind up putting props/state in the wrong place. I found that indeed I had to consider the entire graph when determining props/state. But that this has led me to situations where what my intuition would say would be relatively small changes to the UI create a cascading waterfall of changes I have to make to lots of and lots of components in the existing graph, as where state (including props) is kept needs to change, requiring cascading changes to many components in the previous graph.

Examples of such UI changes would be taking a UI widget/component that previously was only one one page and realizing it had to be re-used on another(s); moving a UI widget from one part of the page to another; taking a UI widget that previously just displayed something and realizing it needs to have an 'edit' capability too; taking something that showed up just once on the page and changing it to be say at both top and bottom of page. All things that my usual techniques and approaches from OO experience would have been able to accomodate no problem if I had designed the components well from the start, but that in React I'm finding result in needing to change where state is kept (or what things are state and what things are props), requiring cascading changes to many components.

Which is frustrating. I hoped I'd get better at avoiding this as I got better with React, and I'm sure that's true, but if even the advice from those most experienced says you can only determine state/props architecture by looking at the entire object graph possibly involved in that state....

I dunno. Comments from people more experienced with react very welcome.

Yeah you definitely need Redux or another state management solution. One of the unorthodox practices React encourages (through the Flux architecture) is to have 'global' state that components can access without passing down props all the time. Currently I limit setState usage to things that only the current component cares about, like if a button is disabled. Every event that may affect another component dispatches an update to the Redux store which holds the global state object.

Some Redux resources:

1) Getting Started with Redux, videos from its creator: https://egghead.io/series/getting-started-with-redux

2) Simplest Redux example (including ES5): https://github.com/jackielii/simplest-redux-example

3) I added Redux to the example app from the docs: https://medium.com/@firasd/quick-start-tutorial-using-redux-...

4) Offical Redux repo, including many examples https://github.com/reactjs/redux

>it sometimes seems like a minor change to the UI can require a major change to the source, cascading through multiple components.

>in React I'm finding result in needing to change where state is kept (or what things are state and what things are props), requiring cascading changes to many components.

It sounds like you don't have a good understanding of state vs props. You should use state as little as possible and try to do as much as possible through props, passing them down from the parent components as necessary.

When I create a react app I use the flux architecture, define a state on the top parent component and then add most of the other components as children to this parent component, passing down state as props, and adding listeners to update the components when the state of the parent changes.

As far as moving elements around I mostly do that through CSS and wasn't aware react had much to do with positioning elements

>taking a UI widget/component that previously was only one one page and realizing it had to be re-used on another(s)

Import it into the component that renders the other page and use different props. If you define a lot of stuff in the state of the component then the component isn't as portable.

>moving a UI widget from one part of the page to another;

This just sounds like CSS and possibly markup to me.

>taking a UI widget that previously just displayed something and realizing it needs to have an 'edit' capability too

Not sure what you mean by this.

Sounds like you could use more practice.


> It sounds like you don't have a good understanding of state vs props.

I think I've got a decent understanding, but I'm sure it could be better, and am heartened to think as it gets better these problems will go away.

> You should use state as little as possible and try to do as much as possible through props, passing them down from the parent components as necessary.

But yes, I've arrived at as little state and as many props as possible. The challenge for me here is that this ends up resulting in components that look to me (based on previous OO experience) like they have TERRIBLE API's, requiring way too many props. My instinct from OO is that a _smaller_ exposed API makes things more portable, but you suggest that "If you define a lot of stuff in the state of the component then the component isn't as portable." Nonetheless, I have moved toward more-props less-state, but....

ALSO this has meant for me that when I need to move or re-use a component from one part of the hieararchy to another, I often end up needing to completely rework the props of a BUNCH of other components, so the right prop can be passed down to my now-moved component -- that's what I mean by 'requiring cascading changes'.

I think it sounds like your data model is a bit too coupled to your component tree.

Try and figure out what the minimal information you need to store is, and keep that higher up.

You can then derive a richer model by applying functions during render().

There's a balance to be found here, if you design your data model without considering the needs of the UI it can be a pain to work with.

The goal is to create a data layer and associated functions which make it easy to extract the appropriate information for rendering a user interface.

Often pain points in React can be alleviated by modelling your data more independently of your component tree.

> ALSO this has meant for me that when I need to move or re-use a component from one part of the hieararchy to another, I often end up needing to completely rework the props of a BUNCH of other components, so the right prop can be passed down to my now-moved component -- that's what I mean by 'requiring cascading changes'.

This sounds like the problem that is solved by redux et al. Instead of passing props into a component just so that it can pass those props down to its children, the child components can just connect to redux and get the data. That way you are accessing the data at the point in the component hierarchy where it makes sense for the component to know about that data, instead of in whatever component happens to be the common ancestor of all of the places that need the data.

Thanks for the feedback!

I had somehow gotten the idea that the common advice was to not use redux/flux until you really need it, and even then only use connect to it in 'top level' components, and pass things down from 'top level' component to children view props. Rather than have every component get things from the reactor itself, even deeply nested children.

Have I gotten the wrong idea? Is the advice I thought was common not actually common?

Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact