Ever since I started pondering [what is React](https://remysharp.com/2016/08/15/what-is-react) last month, the core idea of state driving my development has been on my mind. I’ve been trying to do more reading around React, mostly to understand how to use the APIs available (like creating components, events, etc) and trying to grok any of the magic that wouldn’t be entirely obvious to me on first review of some React-based code.

Today, I spent about 3-4 hours coding up a small part of a project I’m working on. I thought it might be useful to share my thoughts, but also some of the thoughts I had of that first impression.

Big ol-british disclaimer: this post is based on hours of work. Not days. I do not have a full understanding, and it’s likely I’m doing stuff "wrong" (in a similar way that I’ve heard things like "that’s not the Angular way of doing things"). But, as someone who generally avoids adding in large 3rd-party JavaScript, if you’re like me, this might help with some insight.

[I’ve published 38 videos for new developers, designers, UX, UI, product owners and anyone who needs to conquer the command line today.](https://training.leftlogic.com/buy/terminal/cli2?coupon=BLOG\&utm_source=blog\&utm_medium=banner\&utm_campaign=remysharp-discount)

The problem space[](#the-problem-space)

I have a relatively simple web app to build (a closed system with only a little interface to perform a single task). The start of the problem (that I wanted to solve) was simple:

Create a list of items, with a form to add items and a control to filter those items.

And yes, now I put it in writing, that does sound a lot like [todoMVC](http://todomvc.com/examples/react/)!

Setting a benchmark[](#setting-a-benchmark)

I’m good at vanilla JavaScript, and I’d already written a data binding library ("cleverly") called [bind.js](https://github.com/remy/bind.js/), and using bind.js to solve the problem took roughly 30 minutes to code (as the author, I have an deep understanding of bind.js).

Bind.js is a 2-way data binding library that uses DOM selectors to target elements, and an augmented object that tracks changes via setter hooks.

[The solution isn’t super pretty](https://rem.jsbin.com/raboqe/3/edit?js,output), but again, it was 30 minutes of dev and does the trick. However, there’s one line of code in the filter callback that I didn’t like:

this.list.map((item, i) => {
  // ...snipped
  // replace the old entry
  this.list.splice(i, 1, item);
})

The splice felt brittle. It’s also mutating the data in a pretty aggressive manner. Finally, I wasn’t sure I could continue using bind.js for the rest of the app.

Whereas React should be able to do this stuff well (from what I understand), it can do more (like the app routing) and React should also let me move all the JavaScript into the server so that it’s a Progressive Enhancement (whereas bind.js would use PE, but it would be more work and duplication of logic).

Starting out with React[](#starting-out-with-react)

I had a couple of false starts with trying [create-react-app](https://github.com/facebookincubator/create-react-app), [react-boilerplate](https://github.com/mxstbr/react-boilerplate) and another that I forget.

The reason for the false starts is that they contained way too much code and structure and expected understanding. I believe they’ll be super useful once there’s some understanding and ability to navigate the logic behind React apps, but for starting out, I needed to be closer to the metal, I needed to see the direct output of my coding efforts.

Equally, I wanted to avoid build steps at this stage. I’m debugging in Chrome, so I’ve got most of ES6, so I don’t need babel. I am using JSX (which I’ll come to), so I wanted to transform this in the client (obviously for development only).

⚡️ The most useful resource for me, for walking through the code and how the components compose, was [Facebook’s own React tutorial](https://facebook.github.io/react/docs/tutorial.html). It’s good because it takes a comment list and comment box as a tutorial, which I’ve got a good understand how it should work, and I can understand how it would want to be composed together (without even looking at any code).

[James Long’s post entitled "Removing User Interface Complexity, or Why React is Awesome"](http://jlongster.com/Removing-User-Interface-Complexity,-or-Why-React-is-Awesome) is also an excellent, excellent resource for someone like me who favours vanilla JavaScript to understand a problem.

Turning in my grave: JSX[](#turning-in-my-grave-jsx)

I was there at JSConf US in May 2013 when React was open sourced and they showed off the JSX syntax. Many of us also threw up a little in our mouths. But hey, some people (actually: many people) like it.

So what’s to like? And why did I use it instead of vanilla JavaScript when I’m a vanilla guy?

Well, it’s quicker to code, that’s for sure, but [this](https://facebook.github.io/react/docs/jsx-in-depth.html#why-jsx) from the React site nailed it for me:

\[…However] we recommend using JSX because it is a concise and familiar syntax for defining tree structures with attributes.

HTML(like) syntax is concise compared to coding up a new div using JavaScript and then adding each property, making sure strings are escaped (or not), etc.

To be super, super clear though (in my opinion, and I suspect this is the party line anyway): JSX should not land in the client at all. It should already be transformed.

I like writing large swaths of HTML using Jade. I don’t like myself for liking Jade over HTML, but it gets the job done for me.

I gave in to JSX in a similar way. There are some [gotchas](https://facebook.github.io/react/docs/jsx-gotchas.html) documented, and there are some that aren’t (or not in the gotcha list anyway) which I’ll come to.

For prototyping I will need…[](#for-prototyping-i-will-need)

The [React and ReactDOM library](https://facebook.github.io/react/docs/getting-started.html#starter-pack) (which I got from the starter pack), and the [JSXTransformer](http://todomvc.com/examples/react/node_modules/react/dist/JSXTransformer.js) (though deprecated, I had to lift it from TodoMVC/React).

The reason I didn’t want to use babel/browser.js (the recommend client transformer) is that it’s a whopping 1.9Mb of JavaScript, whereas JSXTransformer is 480K. Even when you’re running in development mode and offline, 2Mb of JavaScript is going to slow things down.

Now I’ve got my minimum requirement to start coding. Notice that I don’t have any build tools. That’s good. The client transform costs me the ability to live-code in the browser ([as I like to do](https://remysharp.com/2013/07/18/my-workflow-v3-full-coding-stack)).

Since I can’t code directly in the browser, I ran a local static server using [live-server](https://www.npmjs.com/package/live-server) (static server with live-reload baked in).

The code in index.html looks like this (yeah, there’s [no body](https://www.youtube.com/watch?v=32wer_j5soQ\&index=1\&list=PLXmT1r4krsTrXThZIxcnzogf_YLOHRUZv)…):

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Simple react</title>
  <link rel="stylesheet" type="text/css" href="css/style.css">
  <script src="react.min.js"></script>
  <script src="react-dom.min.js"></script>
  <script src="JSXTransformer.js"></script>
</head>
<body>
</body>
</html>

Composing components[](#composing-components)

"Composing" and "components" were two words that kept coming up, but after reading the Facebook React tutorial, and thinking about how this list would work, it does make sense. I’d need components for the following (pseudo-XML):

<MessageList>    // the app
  <Filter />     // user input
  <Messages>     // list of messages
    <Message />  // individual messages
  </Messages>
  <NewMessage />
</MessageList>

So that’s the Message component being composed into Messages and so on. I watched (at 2x speed) this interesting 30 minute talk on [re-write to React](https://www.youtube.com/watch?v=BF58ZJ1ZQxY). The gist being: the lowest leaf can be written as a React component, and then working up the chain, each component can be refactored to React and composed into the application.

💡 I wondered whether I actually needed web components. Would this do the same job? In theory, they map to regular HTML components (like input, tr, div and so on), so they’re compose-able by default.

But then…I wondered if web components can progressively enhance. I think they can, but honestly, I don’t know. I’ve never felt like they’ve been adopted the way the web developers had hoped.

A sample of the work[](#a-sample-of-the-work)

After \~3-4 hours of work, I got the list and filtering working (I didn’t get the form to create new messages, but I will do).

The main component is the Messages one that looks like this:

const Messages = React.createClass({
  render() {
    const byDate = this.props.data.reduce((acc, curr) => {
      if (!acc[curr.date]) {
        acc[curr.date] = [];
      }

      acc[curr.date].push(curr);

      return acc;
    }, {});

    const dates = Object.keys(byDate);

    const messageNodes = dates.map(date => {
      const nodes = byDate[date].map(data => {
        return (
          <Message number={data.number}>{data.text}</Message>
        );
      });

      return (
        <div>
          <h3>{date.string}</h3>
          <ul className="list">
            {nodes}
          </ul>
        </div>
      );
    });

    return (<div>{messageNodes}</div>);
  }
});

First impressions[](#first-impressions)

🚨 The biggest issue I ran into (that I didn’t understand) was why I had to wrap everything up in a div. The code I thought I could use was effectively above, minus all the `div`s, yet the JSX transform kept blowing up saying it wasn’t legal (possibly the babel/browser library might have helped with better errors?).

I got the answer from a Slack forum that I needed to return a single top-level node. I wasn’t sure what that meant, but now, as I write this post, I realised.

If I transform the XML (in my head) I can visualise that I need to return a single object from the render function: the result of React.createElement(…). It doesn’t matter if that element has many nested elements, I have to return a root element for the render to work. Hence the divitus.

🚨 Once I had wired up the state emitting from the Filter component, up to the parent MessageList which then updates state.data which triggers an update to the Messages, it kinda felt like I was just triggering events and reacting to them.

Similarly to the architecture that the state machine library, Machina.js uses (I recalled this excellent talk from [Doug Neiner at jQuery 2013](https://vimeo.com/67473899))\*.

\* I later read that [components are Just State Machines](https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html#components-are-just-state-machines), which supports my initial gut feeling

But realising this sort of bummed me out. I was using the "super cool" React, only to write everything for myself and just pass events up the chain. Heck (I thought) I could write this myself!

But it’s also things like the onChange properties that make me cringe a little. I’m using writing code that’s DOM scripting, and this doesn’t feel like it is.

This isn’t so at all. I know this without even looking at the code. But here’s the DOM to prove it:

![Devtools react onchange listener](/images/react-input-onchange.png)

Notice that the DOM doesn’t have an onchange and in fact the change event listener is sitting on the document root element. A pretty good approach in my opinion.

🚨 The setup feels very heavy. I also suspect I’m going to have a bit of a battle on my hands when it comes to building for production, because I hate messing around with build tools, and if the boilerplate examples I’ve found are anything to go by, there’s a lot more code and fuss to add.

🚨 Although I’m not horrified by JSX (any more), I would like to try out the same program without it and using vanilla JavaScript to generate my DOM. Even more appealing would be to have the templates in HTML, and have them sucked into my JavaScript and dynamically converted (though…am I just reinventing JSX in the process…?!).

The only additional quirk of JSX is that HTML properties that I’m used to don’t always get applied. I added an autofocus and then autofocus="true" and the final rendered DOM was missing the property. It only worked when I used autoFocus="true"…which wasn’t intuitive at all.

🚨 The "server-side React" articles that I’ve skimmed are making me reasonably confident that I can port all, if not nearly all this code to the server and make it drive the server side rendering (and potentially throw away the client side code…maybe). This is definitely compelling, but I’m not there yet.

🚨 There’s a lot more code compared to my bind.js version, but this code does feel robust. How does that weigh against the fact that I can hack solutions faster when I mess directly with the DOM? I’m not sure.

🚨 When I come across the occasional "Caution: Never access refs inside of any component’s render method" ([here](https://facebook.github.io/react/docs/more-about-refs.html#cautions)) it worries me that a small mistake comes with a \_never\_ warning. Like…how badly will my my browser blow up!?

🚨 [devtools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi) for React isn’t bad either, gives you a view on the component tree I rendered, access to mess with the state directly from the devtools sidebar.

Yeah, but what do you think, Remy?[](#yeah-but-what-do-you-think-remy)

I’m going to stick with it. I feel like if it doesn’t suit the entire application design, then I can either use it for a part of what I’m doing. I definitely feel like moving towards a state managed design is a positive thing for my coding.

I’ll be looking at the React Router next, then porting my code to the server (before I get too deep in client-side code).

I think the next important steps will be to validate code design, typically this would be done with either a peer review or code review for a senior developer. Alas, poor me, I’m not in that position as I work alone (so you may see some random tweets in the coming week!).


TL;DR 🐎[](#tldr-)

  • There’s a tonne of resources out there, but it’s really hard to be sure where to start since there’s so many resources and tutorials.

  • If you’re curious, try to focus on React first, ignore the extra flux, redux, donaldux etc extra bits.

  • JSX isn’t so bad (and made coding components faster), once I got over myself.

  • It all just feels a bit simplistic (at this stage), effectively it feels like a simple state machine and it reminded me of [Doug Neiner’s Machina.js talk](https://vimeo.com/67473899).

Again, this was just a tip of the iceberg. I’m no fool. I know there’s more to React than this. I’m trying to build a web app that uses progressive enhancement as a design principle with state as a core value to the coding approach.

Comments

Lock Thread

Login

Add Comment[M ↓   Markdown]()

[Upvotes]()[Newest]()[Oldest]()

![](/images/no-user.svg)

Pablo Ruan

0 points

7 years ago

Great post. Thanks a lot. :)

![](/images/no-user.svg)

Tracker1

0 points

7 years ago

For autoFocus Think of it as a JS property, not an attribute…​ Like. fooEl.autoFocus=true …​ You use…​ \<foo autofocus="{true}"/> …​. Naming matches the JS conventions.

Note
The comment system is putting quotes around the curly braces and munging the capital F

![](/images/no-user.svg)

Jason Nall

0 points

7 years ago

After all that I’ve heard about React Router, I think I can safely recommend that you avoid it at almost all costs. Let me know if you’d like some more information; I think it’s just going to hold you up and pollute what would otherwise be a good experience with React.

![](/images/no-user.svg)

rem

0 points

7 years ago

Already used it successfully and deployed. What did you experience?

![](/images/no-user.svg)

Andreas McDermott

0 points

7 years ago

Have you looked at Vue or Riot? They both offer similar approaches, but much nicer APIs and don’t feel so heavy-handed. Both allow you to write html-templates instead of jsx also.

![](/images/no-user.svg)

Mark Volkmann

0 points

7 years ago

I’m surprised you found it hard to get started with create-react-app. I strongly recommend that people new to React should start with that!

![](/images/no-user.svg)

rem

0 points

7 years ago

I guess…i should be pleased I surprised you…? Cool!

![](/images/no-user.svg)

Teddy Zetterlund

0 points

7 years ago

Thank you, Remi. Fantastic write-up and an entertaining read. I wouldn’t mind more articles (and videos) of this style.

Your first TL;DR point would do well with a link to Pete Hunt’s [react-howto](https://github.com/petehunt/react-howto) repository.

He summaries the resource pretty well:

There’s a ton of conflicting advice about React out there; why listen to me?

I was one of the original members of the Facebook team that built and open-sourced React. I’m no longer at Facebook and I’m now at a small startup, so I have a non-Facebook perspective as well.

![](/images/no-user.svg)

Marlon Marcello

0 points

7 years ago

You mentioned using Vanilla JS or HTML for the components right? It reminded me of Riot.js.\ You write your components in HTML and 'embed' the javscript.\ You check it out :D http://riotjs.com/

![](/images/no-user.svg)

Michael Rasoahaingo

0 points

7 years ago

Nice post, I totally agree that setting up a React project may be heavy. Have you look at some app builder like [https://github.com/facebook…​;](https://github.com/facebookincubator/create-react-app?) Or another one [https://github.com/geowarin…​;](https://github.com/geowarin/tarec) from my friend @geowarin.

![](/images/no-user.svg)

Fez Vrasta

0 points

7 years ago

I stopped reading when you said that you don’t use Babel because it’s 2mb…​ This is development stuff, you don’t get that on the production build. The problem as usual is that novices of some new tech try to do the things "their way" instead of following the good advices of the more expert ones.

![](/images/no-user.svg)

rem

0 points

7 years ago

And yet, you felt like you had something meaningful to comment here. Nope, having read your entire comment, I can tell you that you didn’t.

Thanks for stopping by and dropping your opinion.

![](/images/no-user.svg)

564765jhgfj

0 points

7 years ago

But he is actually kind of right, don’t take it in the wrong way. I have not seen code and structures like this for a long time and React, for certain, hasn’t been made for it, it is literally designed to be transpiled. By making wrong assumptions you bend things "your way" indeed and wonder why it’s brittle in the end.

Just for kicks, take 4 minutes of your time and follow along this lesson: [https://egghead.io/courses/…​;](https://egghead.io/courses/react-fundamentals)

This teaches you how to use React in a modern environment. If you come back and still think it’s brittle i would be quite surprised.

![](/images/no-user.svg)

rem

0 points

7 years ago

But you see he’s not at all. Sadly some people think it’s okay to wait 5 seconds and more for a build system to be ready. It’s not. Never. It’s a waste of time.

He didn’t read the rest of the post (he stated clearly) so he doesn’t know that I solved the latency issue.

If you’re saying I’m doing it the "wrong way" then this isn’t for me. Same was true then I tried (very briefly angular).

And yet, I was able to deploy a fully responsive, progressive react, redux server side rendered solution for my client inside of 7 days of dev (which included learning all these technologies). Really, that’s to say: don’t tell people they’re doing it wrong. Show them patterns, but don’t waste your time and theirs telling them it’s wrong to bend tech to their liking.

Computers are made for us humans. Not the other way around.

![](/images/no-user.svg)

jpolacek

0 points

7 years ago

For those of you who like JSX but want a more lightweight means to use it in a project, I highly recommend JSRender: [https://github.com/BorisMoo…​;](https://github.com/BorisMoore/jsrender)

![](/images/no-user.svg)

Carl-Erik Kopseng

0 points

7 years ago

The setup does get in the way of learning React. If you just want to get started, and don’t want to have lots of code like you get with all these boilerplates (which will end up being unmaintained like all boilerplates) you should check out [Roc](http://getroc.com) (backed by a major media company) or kyt (by NY Times, not too shabby either, but released yesterday). [Roc’s reasoning](https://medium.com/@DZV/roc-one-solution-to-javascript-fatigue-b14ea07b9763#.4phfmvvwk)) might resonate with you, and it seemed to be aligned with what kyt is trying to accomplish too. One dependency and a clean working dir.

![](/images/no-user.svg)

Evan Scott

0 points

7 years ago

I maintain generator-enigma, and I feel it does an excellent job. Very much gets out of your way and just sprinkles in what you need to get going. [https://www.npmjs.com/packa…​;](https://www.npmjs.com/package/generator-enigma)

![](/images/no-user.svg)

Kelly Campbell

0 points

7 years ago

On JSX, I felt similarly at first, and then grew to really like it. Someone wrote a great post which I can’t find now, but the gist of it was how every template language has its own syntax and different ways to do looping, and reference variables and stuff. With jsx, you’re not writing in a template language. It’s just javascript expressions. You already understand the syntax of examples and such.

If you run with react in dev mode (NODE\_ENV=dev or just NODE\_ENV != production I think), the browser console should give you warnings about mistakes like the autofocus vs. autoFocus and other common issues like if you access refs or change state from within the render method.

![](/images/no-user.svg)

matthewholloway

0 points

7 years ago

autoFocus is because that’s the JavaScript standard’s casing for it. In JSX you can also just use autoFocus on its own without an attribute value.

![](/images/no-user.svg)

matthewholloway

0 points

7 years ago

(ok before someone jumps on me for this.. it’s prob the HTML5 standard not the JS standard)

![](/images/no-user.svg)

cody lindley

0 points

7 years ago

Might find some of this useful. Maybe? [https://www.reactenlightenm…​;](https://www.reactenlightenment.com/)

I take a learn React only approach. Even before you learn JSX.

![](/images/no-user.svg)

ChrisG

0 points

7 years ago

Great post Remy. I took a similar approach when learning React. If you get a chance checkout http://mithril.js.org/ it has less magic, less tools required, and more "just-javascript".

![](/images/no-user.svg)

Andrew Powell

0 points

7 years ago

I’ve just started scratching the surface, but I find Aurelia tends to win on all of your gripes about react. I’m loathe to use JSX (it reminds me too much of the wild west of ASP.NET days, mixing code and custom tags) and Aurelia makes excellent use of templates. http://aurelia.io/ it’s worth a look.

![](/images/no-user.svg)

Evan Scott

0 points

7 years ago

Aurelia and React aren’t even comparable, imo. Like comparing a Ferrari to just an engine. Personally, I find the React ecosystem and usage patterns easier to understand and onboard others.

![](/images/no-user.svg)

Tim Arney

0 points

7 years ago

Great post Remy, I always find it interesting to get perspectives from people starting out with React.

I started a repo that might be helpful as far as resources [https://github.com/timarney…​;](https://github.com/timarney/react-faq) . As you mentioned there are a tonne out there. I’ve been trying to curate some of the better ones I have found.

![](/images/no-user.svg)

Jeremy T

0 points

7 years ago

Something to keep an eye on when you’re using an array inside render: React will be smarter about how many DOM updates it has to do if you give each of your array elements a key prop.

[Commento](https://commento.io)