Typed take-aways from the React Advanced Conference 2019
I attended the React Advanced Conference 2019 and have written some notes on what I absorbed. Here are a couple of talks that I particularly liked, on topics that I’m currently interested in learning more about.
Don’t Let Your Unit Tests Slow You Down — Daniel Irvine
I really enjoyed this accessible and engaging talk.
Daniel Irvine started by saying that TDD is not about unit testing, and that his talk would not cover TDD, as it is a wide topic in itself. However, he did make it clear that unit tests are your ‘bread and butter’. They are essential to the smooth running of any product.
Not everyone is a Rockstar Developer; which I interpret as comparable to the 10x dev. Which means that not everyone can sit in a corner, not speak to anyone, and write a big chunk of code in a few hours that works first time and follows the specifications. Even if you do that, how many other devs will ever be able to easily understand and adapt that code if needed in the future? Can you write a test for that?
Unit tests are about following requirements that the whole team understands and benefits from. Unit tests mean less time for a dev in the future to spend decrypting some chunk of code that even the developer who wrote it may not remember. I can’t even remember the amount of times I look at code and wonder who on earth wrote something like that, only to find it was me, some months back.
Unit tests are important for regression testing. Yes, both QA tests and dev tests do offer regression testing, however dev tests help with things that QA tests don’t. Such as when it comes to refactoring. They help explain our code to others and they can minimise debugging and manual testing. It’s often a good idea to go through the tests in a codebase instead of jumping into someone else’s code to start debugging.
As a general guideline React unit tests should:
• include the render component
• test the lifecycle
• not! test the state
The React component tree can be confusing when unit testing. If you have some tests that are further up the tree, and especially if you haven’t used mocks, you will often not be able to find why a test is failing. However, if you write a test further down the tree you will have much better coverage.
Daniel Irvine gave an example of a ‘mess of code’ as writing one long procedure in the smallest amount of code. This is not helpful for readability and stops tests from being easily written.
Testing components is complicated, but testing objects is not. Frameworks such as React can be tricky with unit testing, but remembering that unit testing works best with objects can help a lot. As a rule, don’t use things like conditionals in tests, your business logic should be elsewhere.
A good bit of advice; your aim should be to build something adaptable. You don’t want your app to be framework specific, you don’t want a React app. You want to an app that you can ideally adapt to any technology sometime down the line when things change or you need to add something new.
Some great ideas to get deeper into testing and help make tests easier to write and understand is to try to write your own test library, as you will learn a lot. It is also well worth pairing with experienced devs. Reading TDD books can be a great help too.
There is a limit to how much depth you can go into during a short talk, and the best talks inspire me to learn even more about a topic. I will definitely be learning more about testing, and I plan to read some books! Daniel Irvine has actually written one himself called Mastering React Test-Driven Development.
At the LEGO Group I have paired a lot with my squad’s test engineer and I have found it has really helped propel my learning.
Statically Typing JavaScript — David Gomes
We were asked how many of us use Flow. I looked around the room, and about 10 people out of the 500+ there raised their hand…Then we were asked who uses TypeScript. I looked around. Apparently everyone else in the room!!
When Flow was being developed at Facebook, their goal was for large scale performance while type checking the codebase. Type inference was a priority, as well as catching errors.
When TypeScript was being developed at Microsoft the focus was on dev tooling, adoption and being open source.
David Gomes has experience with both on a single project. Firstly it’s useful to note that the syntax is very similar.
On the topic of their similarities, JavaScript is a very dynamic language. For example, if you multiply null by 3, the result is zero. Neither Flow nor TypeScript allow this. Both make the decision not to permit things like this. Also, Flow and TypeScript expect a number from an array of numbers, even though you could be returning undefined.
There are quite a few differences too, and mostly it comes down to TypeScript being more lenient than Flow. Also, things like TypeScript using structural typing for classes while Flow switches to using nominal typing.
I looked up some of these differences myself, and I found that there is actually a handy table of differences for those who are curious.
TypeScript is purposefully unsound in some cases because it is more convenient, which is how it prioritises being accessible for developers to use. There are some tricks to make it more strict however. Flow does have better type inference, but TypeScript is catching up. David Gomes recommends TypeScript for the majority of applications but mostly wanted to leave us with the message that gradual typing is here to stay.
If you want to read his article about porting 30k lines of code from flow to JavaScript, it’s an interesting read!
Design Systems — Siddharth Kshetrapal
Siddharth currently works at CodeSandbox, and previously worked on the AuthO design system.
We can think of a design system in its most basic form, as a CSS library. A design system will usually include integrated principles and patterns that define the product and can be shared and reused; it is essentially made up of repeatable and reusable blocks of UI. Everyone should be able to use the same patterns and principles, and it should be understandable by everyone.
A design system is about creating a common language. It is part of a wider system that can help with communication flow and make requirements much easier to understand and follow. Very significantly, this can happen across multiple teams; product, marketing, design and development. It can be a very useful tool for brand consistency, making the brand even more cohesive and recognisable.
A design system usually includes the following:
• Styleguide
• Shared component library
• Shared variables and assets (and if using React — React components)
You can include very specific guidelines like ‘on a form, the highlight should be first, then the error message, then a dialogue element to loop back to the start of form’. This kind of detail and shared information means that it won’t have to take a week to write a two field form, and it involves less back and forth between product and design teams.
In your system you can cover everything from styling and accessibility through to TypeScript and GraphQL. Being able to separate tasks between the ‘front of front-end and back of front-end’ can be helpful.
When GitHub was using Auth0, they came across a problem where the components offered were not flexible enough. Auth0 found a need for a way of having brand consistency across multiple types of services. Different websites and different types of content belonging to the same brand will need to follow different UX patterns.
For example:
• marketing content
• a blog
• the product
These all need to follow slightly different design patterns. Siddharth found that reusable variables are important but it’s also important not to abstract too early. First design the design system.
When Siddharth started at CodeSandbox he found a number of design inconsistencies, and people were rebuilding simple elements over and over. There are ways you can help ease this kind of problem with a design system, but it’s important to remember that not every problem can be solved that easily.
The solution is not always a design system. Siddarth said: “If all you have is a hammer, you look for a nail”, yet it is good to see a design system as a Swiss Army knife, not a hammer. This is a great analogy; you can use many tools from a design system and you don’t have to use it all as one single solution. Instead, it is more like that Swiss Army knife, with multiple solutions and helpful features. An important bit of advice was not to overcompensate by using too many tools.
Siddharth offered a lot of ideas and thoughts about how you can make a Design System work (or work even better!) for your team. One idea was to follow constraint based design. It can be beneficial to have limited options which you make readily available for use and are shared across your platform/product.
Some people will be interested in state and types, and some will be interested in design. It’s a real strength to have a mix of interests and experience in a team. Because of these differences, it’s really important to make it easy for others to follow the consistent design, so make the constraints easy to access, which should discourage bad copy pasting or people having to redo everything from scratch.
You can do handy things like:
• integrate with Visual Studio Code
• integrate with Invision or Figma
Importantly, make sure your documentation is easy to access, organised, and kept up to date. You can read other people’s good documentation to help inspire and guide you in creating your own.
You can find out more about Siddharth and design systems on his blog.
There were a lot of good talks, and I didn’t manage to find the space to absorb and write about all of them. There were two tracks at React Advanced, so I definitely recommend checking out the livestreams that were recorded! They may release individual videos soon so keep an eye on GitNation’s YouTube Channel to watch up to date videos.
Hannah Tucker McLellan is a Junior Application Engineer at The LEGO Group
Twitter: @hannahintech