React Training came to Melbourne

Welcome to the wonderful world of ReactJS, the solution to all your problems!

Well, maybe not all your problems but I’m sure we all felt pretty good after thirty odd REA’ers were lucky enough to attend an in-house course about ReactJS run by Michael Jackson (as much as I’d love to fill this post with puns regarding the obvious, I’ll try really hard to refrain).

The trainer

Does he need any introduction? Probably not so we’ll just cover the stuff that you don’t know about him.

Michael is a US native, passionate technologist and gifted speaker. Who would have thought he was so multi talented? Apart from the open source libraries he has contributed to and created (think React Router), he is also known for co-creating React Training, a company that specialises in…err…React training. The company runs a variety of courses that cover basic and advanced React, run either as workshops or online courses.

Within five minutes of Michael commencing I felt that this would be at the very least an entertaining course. After enduring more than my fair share of dry, old uni lecturers that could put a red cordial powered kid to sleep this boded well for the next few days.

The people

We had forty nine people attending the workshop on the 8th-10th of February. We had people who were complete newbies with regards to React intermingled with people who could probably have taught Michael a thing or two. Although priority was given to REA staff we still had eighteen people attend from external companies. It was great to give other people the opportunity to get a sneak peak inside the REA offices to see how we work.

There were positive signs for our gender balance as well, with ladies making up over 15% of the audience! Let’s keep working on pushing this up.

The workshop

Over the course of the three days we covered a myriad of topics, starting with some fundamentals before moving onto a couple of days of more advanced React. The bulk of this post will be broken down by the topics covered on each day – hopefully I can provide some useful pointers for those who were unable to attend.

Day 1 – React Fundamentals

Intro

Michael kicked off proceedings by giving us a brief history lesson on UI development, delving into the evolution of different technologies before finally landing on ReactJS. I found that in particular he nicely articulated some of the problems one encounters when using templating engines such as Handlebars. One common problem is when people need to do things outside of what the template language supports, which generally involves writing specialised language features backed by pure JS code (component code). This adds a cognitive overhead for people reading the templates as they need to either understand the new constructs on top of the template language or perform mini context switches (jumping to the implementation) to understand it.

Enter JSX – for some a particularly contentious language construct that allows for inline HTML template code (well, it looks mostly like HTML). That’s right – your HTML lives directly alongside your JS code! I’ll admit that when I first saw this at a YOW talk a few years back that my first thought was NOOOOO! You can’t go combining your UI code alongside your application code! Well, it turns out that you can and it works – partly because React is only a view library. That needed emphasis because it’s really important. Think Angular except with no model. Or controller. Or routing. Or anything other than the view.

I’ll put it out there – frameworks that are focused and designed for a single purpose are always better (disclaimer: this is just my opinion).

After the history lesson we moved onto the fun stuff – we started delving into React fundamentals. I think most of us who had React experience thought this would be a case of heard it, know it but it was actually a really good refresher. Michael’s style for each topic was to begin by discussing a problem before moving onto how it’s solved by React. Every topic involved a practical hands on exercise where we all paired up to solve the problem (first rule of React Club – you never code alone).

Let’s just get some housekeeping out of the way. Michael provided us with a Git repo that included all of the exercises (and solutions) along with a nice harness to run everything along with live updates. For those interested, you can view this here, however without the added context of Michael speaking much of this will be meaningless – you should just go and do the training. If you happen to be interested, you can find the course syllabus in that repo as well. Finally, there’s also a nice little ES6 primer for those more familiar with earlier versions of JS.

So let’s get to it.

Hello World

Could there possibly be any other way to start other than this? This was the simplest of simple exercises – update the code and see the change reflected immediately in your browser. It’s brief enough to show in it’s entirety:

Pretty basic, right? This format of exercise is how they were all structured – a simple React app with some comments at the top explaining what you needed to do. Whilst putting together this post and perusing the training repository I did stumble across a markdown file that covered some of the historical stuff that Michael talked about in his interesting. A worthwhile read.

Let’s move onto something a bit more interesting.

Rendering

Michael started by delving into the basics of rendering in React – he talked about the virtual DOM and delved a bit deeper into what JSX is (syntactic sugar for the React API to create the virtual DOM) before we jumped into the exercise. We needed to manipulate an array of food items before displaying them in a list. In doing so we were exposed to the basics of how React renders data – nothing groundbreaking but a nice gentle introduction nonetheless.

Whilst writing this section I also came across a nice writeup on JSX and the virtual DOM – worth a read if you’re interested in this topic.

Components

This is the bread and butter of React – reusable components that form the building blocks of apps. Our exercise was to take an array of country data, rendering each country as a separate tab. We were provided with a bare bones Tabs component that did not much of anything and needed to get the data in there and allow the user to click between the tabs.

I was pairing with the super impressive, Mr Functional, Dan Stankevich. He was driving and I couldn’t quite figure out why the first thing he did was to reverse the country array (which caused the tests to fail):

And then I remembered that he’s Russian. He kind of resembles this guy so I was like totally cool with his change.

The rest of the exercise was pretty straightforward and we solved it with suitable aplomb (after reverting the reverse of course) before moving on to the next topic.

Props vs State

Understanding when to use props and when to use state is quite important and I felt that Michael gave this some really decent coverage. Think of state as data which changes over time and is generally associated with user interactions (but not always). Props are a means for a parent to pass data down to a child.  The key thing in building components is deciding where to manage state. Although there isn’t a golden rule, it’s nearly always advisable to minimise the state held within a component as this can really increase the flexibility of your components.

Luckily, the exercise we worked through did a pretty decent job of showing the difference. We started with a stateful tabs component (shown just below) that managed which of it’s tabs was selected. As a self contained component this works just fine. But as Michael asked, what happens when you want some other component to control what tab is active? Without resorting to some funky hacks this would be difficult to code and maintain.

The solution is to pull out the state (the currently active tab) and allow this to be passed in as a property instead. The API to the component (essentially the props it receives) was changed to take in an activeTabIndex meaning that this is managed external to the component. Viola! We have a remarkedly more useful component now.
I found this session to be really useful – understanding when to use state vs props, and in particular where to place state is crucial to building flexible and maintainable React apps. Take note all!

Imperative To Declarative

Things really started to get interesting now. One of the selling points of React is it’s ability to support a more declarative style of programming (think functional programming) vs the more common imperative. To highlight the different styles I’ve included a brief example of doubling an array of numbers using both an imperative and declarative style.

As you can see, the imperative function involves telling the language exactly how to go about doubling the array. Create a new array, loop over the numbers to double, double the value and then push it onto the new array. Finally, return the new array. In comparison the declarative approach simply declares what we want to do without actually providing all of the plumbing to do it.

A declarative style of programming lends itself to all kinds of niceties. The good news is that there’s plenty of good literature out there on the internet that explains it. If you don’t understand the style then do yourself a favour and read up on it – your React components (and other developers you work with) will thank you for it.

The exercise itself was to take a component that had an imperative API like this:

and convert it to a declarative API. If you look at the above modal and wanted to work out whether it was open or closed, how would you do this? Presumably you’d have to know whether the `onClick` callback had been called – which means you need to understand the component over time to understand it’s state. Now look at the declarative solution:

Very similar but notice the subtle difference? The modal now contains an isOpen property (which is drawn from the parent component’s state) that declares whether it is open or closed. As long as the openModal and closeModal manipulate this state the modal will be rendered correctly. Now it’s easy to understand whether it’s open or closed – you simply need to interrogate the state.

Again it’s really important to understand the distinction between these two approaches so like I mentioned please go and read up on this if none of this makes sense!

Side note: Michael also gave another really good example of imperative vs declarative using a Theremin player – you can find it here. It’s cool, and fun to play with, you should check it out.

Day 2 – Advanced React Part 1

Compound Components

I remember not really having a clue what this topic was about when we started it – I came out the other side quite enlightened. The idea is to create components that are easily extensible without having to constantly tweak and modify their API (remember, this is the props the component receives). Michael walked through a really nice example that’s probably more instructive than the exercise so I’ll focus on that.

Imagine you have a tabs component that renders an array of tab data. Using it within a component might look something like this:

Certainly straightforward enough – it’s easy to understand and most people wouldn’t have any objections to it. Now if I asked you (as Michael did) how you extend it to support placing the tabs at the bottom, what would it look like? Maybe something like:

So now we’ve extended it nicely to support this with the addition of a tabsPlacement property. Again it’s easy to understand – all good right? Now how would we support disabling tabs? If we draw inspiration from the jQuery API this change might look something like:

We’ve added a nice little disabled property that accepts the indexes of the tabs to disable. What could be simpler?

You may notice a trend occurring though – every time we wish to extend the behaviour of our tabs component it’s API is extended. This approach isn’t inherently bad, particularly for small, confined components, as it allows for nice, concise API’s. However it does mean that we have to keep modifying our tabs component to support these new properties.

So what would be an alternative? You guessed it – compound components. You’re a star! If we pull apart the tabs component into several smaller components, we could construct tabs however we want. Want tabs on the bottom and the second tab to be disabled? Sure, we can do that:

Want tabs at the top and to disable both? Easy, just swap around the TabPanels and TabList and add an extra isDisabled flag to the tacos tab.

This kind of flexibility comes with the cost of the parent component needing to be very explicit in how it wants the component to be constructed – the parent now needs to be aware of all of these sub components. This cost needs to be weighed against the flexibility one gets with this approach.

Context

Beware! Here there be dragons! Or so it be told in the documentation for React context:

The context gives developers the means to pass data down to components, completely bypassing the standard means of doing this, which is by threading data down through props. It’s somewhat mysterious and mystifying which is probably what makes it so tempting.

Michael gave some insight into why the React developers built in support for this – it all came out of a possible need to support routing! (or at least that’s how I remember the story being told).

The exercise itself involved using the context to pass down a callback function to some child components – we’d done this previously by mapping over children and decorating them with extra props. The benefit to the context approach is that you can support an arbitrary level of nesting, for example:

It would be difficult if we wanted the Form component to pass the onSubmit callback to the TextInput and/or SubmitButton component due to paragraph tags which are the direct children of the form. If using the context it’s relatively simple for the form to indicate what child context types it’ll support and for child components (at any arbitrary level of nesting) to register an interest in accessing these.

The one thing that redeems the context is that the consumer of the context must explicitly specify what it is interested in pulling out of the context – this does provide at least some assistance to developers maintaining the code.

Forms

No UI development course in any stack would be complete without looking at how forms are dealt with.

Michael’s explanation of forms was quite interesting because it touched upon a concept I hadn’t previously come across in React – controlled vs uncontrolled components. The basic premise is quite simple – in controlled components user input is responded to (and possibly held) internally within the component, usually via state. In uncontrolled components it’s the DOM managing the values in the input controls.

One of the advantage of controlled components is that it enables the component to be fully in control of how it renders (it’s effectively the single source of truth). It also makes it easier for the component to respond to changes in state – a change in one input, which updates the state, results in the component being re-rendered.

The example exercise given was a checkout form where we needed to support duplicating the billing address as the shipping address if a checkbox was ticked.

Making the component controlled made the billing name and state easily accessible from the state, which in turn made it easy to set as the billing address when the Same as billing checkbox was ticked.

Day 3 – Advanced React Part 2

Higher Order Components

I think most of us were eagerly awaiting this one as we’re big fans of HOC’s (as we fondly call them) here at REA. HOC’s are really useful for adding cross cutting behaviour to components without needing to modify the components themselves – think the decorator pattern. There has been plenty written about them, with the best writeup by our very own Mehdi Mollaverdi.

As an exercise we needed to write one that would listen for mouse events and rerender the wrapped component with the current mouse coordinates.  Have a look at this for some sweet code!

You can see from this example how powerful and expressive (via the function name) these can be. HOC’s are pretty widely used in various open source libraries. Most people who have been using React/Redux would be familiar with this bit of code:

The connect function, from react-redux, is both a curried function and one that returns a higher order component when invoked with the second argument. In this case the HOC is responsible for listening to changes to the Redux store, mapping the Redux state to props (via the supplied mapStateToProps function) before rendering the provided Component.

It was also pretty obvious that HOC’s, whilst wonderfully useful, weren’t necessarily Michael’s preferred approach for adding in cross cutting concerns. More on that soon.

Implementing Redux

Since we’re on the topic of Redux, it’s quite fitting that it was the next topic. Quite a few of us had watched Dan Abramov’s Egghead course on Redux where he basically rewrites the Redux store in minutes. The man is clearly a genius and not of this planet – but that’s neither here nor there. Focus…

But as it goes, we can all do it as was proven by the exercise in this topic. In this we were given a partial implementation of Redux and asked to implement the connect HOC along with the Provider to make the store available to connected components via the context. Boy was it fun! We’re all from other planets!

Render Props

I think by this stage many of us were wondering whether we’d cover the comrade in arms to HOC’s – functions as child components, or FaCC’s as we call them. Again, THE article on FaCC’s has been written by Ken Ding‌ – get it here before it sells out.

Now whilst render props are not exactly the same, they are almost identical. In fact I think render props may just be a different name for the same pattern.

For those who haven’t read up on FaCC’s they look something like this (this is a simple feature toggle implementation):

As you can see the children is not an array of React elements but a function. The FaCC is responsible for defining the signature of this function and then invoking it with the appropriate arguments.

If this was implemented using the render props pattern as described by Michael this would look something like this:

As you can see, aside from giving the rendering function a name they are semantically equivalent.

Michael was certainly a big fan of render props over higher order components. He gave a brief example of what the aforementioned connect from React Redux would look like as a FaCC. Like all things though, there are compromises that must be considered with either approach. Ken nicely detailed the differences in his article:

Routing

After the good meaty topic of render props we moved onto some lighter weight material – routing in React apps. Or more specifically, routing using React Router in React apps. Given Michael’s involvement in React Router it came as no surprise that he was quite animated and excited to talk about this topic!

A lot of the discussion and corresponding exercise was around the latest release of React Router (version 4). It’s fair to say this release was quite contentious in the community due to the API changes, in particular the ability to nest routes deep down within your component hierarchy. It’s a thankless task providing free, open source software.

This topic did get a few of us thinking about whether there were alternatives to React Router that perhaps aren’t as coupled to React. I did some googling and stumbled across Navigo which looked quite interesting – some quick hacking and I had some basic routing happening in our sold app! Again, this is one of those libraries which is small, focused and does one thing only. A bit like React really. I like.

Animation

This was the topic that held the least interest to me – my web skills run more along the vein of the cookie cutter rather than creative style. Thing blocky table based layouts rather than flex-boxy animated interfaces.

The focus of this topic was on doing animation in a declarative style – the React-Motion library was used as an example of this.

The actual example was pretty cool – some spring based animation that allowed you to tweak stiffness and damping values. You can find the lecture code here.

My notes

I find when I participate in courses like this that I come away with lots of useful pointers – not always related to the course material but just thoughts and little tidbits that may be useful although YMMV. Here’s some of the stuff I wrote down, hopefully you’ll find something of use in here.

  • React: render functions should not have side effects, they are just getters for JSX
  • React: debugging state – insert <pre>JSON.stringify(this.state, null, 2)</pre> into your JSX
  • Chrome: select an element in dev tools then type $0 in the console, which will print the selected element. Select another element and the first becomes $1
  • React: you should never need to use refs on components that you create! It’s ok to use it on things like <input>, etc. For example, <input ref={node => this.node = node} /> to store a reference to the input node.
  • HTML: <input> elements without name attributes are not submitted when part of a form
  • React: only store data in state that is used for rendering. This also means you should not submit the state when submitting a form, serialise the data from the form itself (there’s even a library to do this)
  • React: if you want something else to control input values, make the component a controlled component

And even though there are a gazillion of these on the internet, let’s end with a React lifecycle cheatsheet.

Lifecycle method Useful for…
componentWillMount Setting the state before an initial render
Starting timers, setting instance vars, setup-y kind of stuff
componentDidMount Doing DOM stuff (web audio, sizing elements, adding event listeners, etc)
componentWillReceiveProps Setting the state in response to prop changes
componentDidUpdate Doing DOM stuff (after the DOM is updated)
componentWillUnmount Cleaning up your component – stopping timers, removing event listeners, etc

The wrap

This has been a most excellent adventure!

People seemed really chuffed to have taken part in the training and there was a really good buzz amongst the group. I believe that we all came away better for the experience. It’s not easy teaching a technical subject in an interactive and entertaining fashion and I felt that Michael nailed it.

On the first day he presented topics many of us understood in a new light and I’d be surprised if anyone didn’t take something new away from the day, even the seasoned campaigners. The advanced topics on the last two days were relevant enough to generate some great discussions amongst ourselves around how we structure our apps. Couldn’t ask for more really!

Courses like this don’t just happen – lots of hard work was put in behind the scenes to bring Michael across and ensure we had as seamless a learning experience as possible, both for REA staff and externals. Many thanks need to be given to the following people that made it all happen.

  • To Alyssa Biasi‌ and Shane Gibb‌, the drivers, protagonists and general head organisers at our end. None of this wouldn’t have happened without them, thanks!
  • To Daniel Haughey‌, the man who holds the purse strings, thanks for seeing the value in this!
  • To Milly Rowett‌ for designing wicked t-shirts – what would a training course be without them?
  • To Laura Naim‌ (and the rest of the Facilities crew) – wow, our facilities team rock!
  • To Peter Moran‌ for filling in for Daniel H at our Q&A drinks after day 3 closed. Very polished performance, we might just have to invite you back.
  • To Ken Ding‌ – nothing happens without troops on the ground to help with general legwork, good stuff!
  • To Nigel Dalton‌, Tomas Varsavsky and Alex Zaharakis for sitting on the Q&A panel and answering all the questions
  • To Oliver O’Dell‌ for giving up his time to show external people how passionate REA are about VR and AR. Innovation rocks!
  • And of course to Michael Jackson for so clearly wanting people to learn React and being able to bring people on the journey.

I know I’ve missed people. I’m sorry. There are always people behind the scenes that get a “…and to everyone else who made this happen, thanks!” – you know who you are.

And that’s the wrap.