Notes on Learning React
I hate trying to learn a framework in the middle of its teenage phase. Maybe it has more than a few devoted followers, some production apps under it’s belt, but has not yet entered stable, grownup framework life. Trying to understand something in the middle of those big, volatile changes is awkward. It reminds me too much of trying to be friends with the mean girls when I was in 6th grade. Code samples from a month ago will suddenly be sooo last month.
When we first moved our app over to Ember, the framework was in the midst of a growth spurt. Documentation was generally good, but code examples were often out of date. I do love Ember. The Tomster couldn’t be cuter (please checkout Mascots, if you’re into that kind of thing). However, the learning curve was steep & rocky. “Pods!” they said. “No, pods are dead” they said a few months later. Then they followed with “Actually, pods again, but slightly different pods this time!”
So we decided to write our next app in React. Yes, I know, duh, not a framework. But let’s be honest. In most cases it has effectively replaced Backbone, Ember or Angular rather than sit alongside them.
The hardest part about getting started with React was, well, getting started. After you’ve experienced the beauty of ember-cli, the complexity involved setting up an application harness from scratch is pretty daunting.
Luckily there is now a similar project for React called create-react-app. It will give you a place to get started so you can focus on learning to appreciate the beauty and simplicity of React before diving into the trenches with a wrench and the webpack docs.
React is still experiencing some growing pains, but so far I’ve found the learning curve to be much gentler than other frameworks. Maybe this is because React is so much less opinionated. Not in the grumpy grampa way that Backbone was indifferent, but in a way that gives you just enough control without overwhelming you with decision-fatigue.
Code samples from a few months ago still work, even if they look a bit different from what you’ve just learned. There is a lot of flexibility to organize your app the way that makes the most sense to you & your team. You can write a component using ES6 class syntax and a constructor, like so:
An alternative way of writing the above component would be the slightly older syntax of createClass() and getInitialState(), like so:
Both of these components do the same thing. Personally I prefer using the newer class syntax, but then you have to bind this. However, in future versions of React the createClass method will no longer be part of the standard library, so it’s best not to start a new project that way. It’s also a bit cleaner, IMO, to use class syntax. You don’t put commas in between your methods and variable declarations. With cleaner function declarations in ES6, your code will actually start to look very readable. (Note: you will need Babel to use most of the cleaner ES6 features in most browsers).
It is great to have flexibility, but this can make it harder for team members to read each other’s code. So you should probably choose one way and stick to it throughout your project.
For our latest project we mostly use ES6 class syntax and stateless functional components. Not surprisingly, these components do not have state. If you have a bug in your React code, the most likely culprit will be state. By removing one of the moving parts your component is easier to debug and test. This type of component will look like a function that accepts arguments.
In our previous example, the component both handled the logic to update the count when the button clicked and displayed the button. You could have the click handler in another component. Now this component only displays data and doesn’t worry about how it got to it’s current state.
That example feels a bit contrived, so here is a real-world one. In our project we decided to write our own modal. The modal header has a simple job. It displays a modal title and an optional close button. All of the functions and the title are passed in, so this component’s only job is to render.
If you are lucky enough to be one of those people who stands on your desk waving a giant spoon & ranting that “ES6 classes aren’t really classes!!!”, then I’m sorry but class syntax is nevertheless in your future. If a project already has hundreds of createClass() components, there is likely no reason to refactor right away. Starting a new project, you’ll be better off using the newer syntax.
If you have great test coverage, refactoring is a snap, though, amiright? Syntax will always change as frameworks evolve. The best way to future-proof your app is to write tests that verify behavior will remain the same, even if implementation details change.