The Would You Rather Refactor
The product story behind the major refactor to the Magis app (formerly Would You Rather), Udacity's React Nanodegree second project, based on React & Redux.
Last March I joined the Udacity’s React Developer Nanodegree (RDND). I did it mostly driven by curiosity, a passion for coding and crafting digital products. Most importantly, I did it as a way to relate and connect in a more profound way with our team of engineers.
Don’t get me wrong, though, I have never felt like an outsider, on the contrary. I am an engineer myself. I have been surrounded by talented engineers my entire career: at college, of course, at iomando, at Ironhack — first as a campus manager, and now as a product manager.
Coming from a technical background has given me an “unfair advantage” relating to other software engineers — despite dealing mostly with the management side of things — participating in technical discussions and comfortably sharing opinionated ideas about our approach to software development.
Yet at the same time, web development moves fast, and I started to sense that React — one of the most critical pieces of our stack — was outpacing me in many ways.
I had to learn React, I owed to my team.
Long story short — if you rather want the long version check out the RDND in-depth post — late July I delivered the last project of the RDND. Yet I finished the Nanodegree feeling that I rushed through the thing. Like I just put a ton of strings together that made some React-sense and wrap them up onto GitHub repos in order to graduate. But didn’t digest the best practices, didn’t master React’s foundation. Somehow, it missed the point.
Because of that, I promised myself that as soon as I could put some more “side-project time” together I would go back, review them one at a time, and implement all the cool things I kept on learning.
It took me almost three months to find the right time, but finally, the last couple of weeks have been all about updating the Would You Rather project — the second one of the RDND.
This project consists in a small quiz game, built with React & Redux, that quizzes the user with polls in a “Would You Rather…” format. It allows the user to log in, post polls and also vote on polls posted by other users.
I chose to start working again on this one because it was built on top of Redux — which I really liked, but also because it was the one that seemed to have the most room for improvement. During these past two weeks, I set aside almost every evening (and some nights, too) to work on a fully revamped product: from the UI design fundamentals, down to the component structure and the way the data is fetched and handled throughout the app.
In a nutshell, what impressed me the most after going deep again into the project was, first, how quickly you forget about the code you wrote just three or four months ago; and second, yet closely related, what an embarrassing experience is to go through your “old” code. Which I’ll take as a good thing since it means that you’re learning and skills have improved.
The app now retains less than 25% of the original code I delivered back in May, while reducing the total lines of code by more than 30% — achieving, of course, feature parity with the older version. I really didn’t know where those metric belonged in a performance scale for an amateur. After consulting with many fellow developers that know a thing or two about it, I have been told that it is pretty impressive 👍.
On top of that, the app loads faster — mostly because I got rid of the Material UI library (more on that later), but also improved the way asynchronous calls were managed since they were taxing the app performance.
The app comes packed with many new features under the hood, but I’ll try to cover the most important things spanning from the design of the UI down to the refactor of some critical components.
Designing with Figma
I don’t want to turn this into an unconditional love letter to Figma, but I totally could. Figma is probably one of the most incredible pieces of software I have discovered this year. There is plenty already written on the Internet about its magnificence, but as a side note, I’ll just go on about what it meant for our product team, in particular.
We basically narrowed down our design stack from four separate tools…
- (1) Sketch — to design the thing
- (2) Abstract — to keep every designer within the team in-sync
- (3) InVision — to validate prototypes with stakeholders
- (4) Zeplin — to share the final designs with developers
…down to a single product, Figma — without losing any features nor accepting any tradeoffs along the way. This is definitely not something that happens very often.
Because of that, I was already interacting with Figma but never had the opportunity to get my hands dirty. Moreover, one of the things that I regret the most (again, going back to the point of rushing through the Nanodegree) was that during the program I didn’t have the time to actually design the projects. But instead jumped straight to the code editor — not something that I’m proud of. In other words, I would have never encouraged my team to do such a thing, but I clearly didn’t eat my own dog food here.
So I started — as it should be — from the very beginning. Designing each component in advance, every state it went through the app lifecycle. The journey started with colors and typography. In this regard, I cheated a little bit and used Ironhack’s color palette. For the fonts, I used a combination of Fira Code and Fira Mono.
Now that my love for Figma is already confessed, let’s move on to the design of more interesting things like…
The Poll Card
Later on, I set out to reimagine the most critical UI component: the poll card. I aimed to keep the voting experience as simple as possible, yet it still took two taps to vote from the home page.
This was not a deliberated product decision, but the consequence of a technical constraint I couldn’t get my head around at the time. Fortunately, my coding skills seem to sharpen up and I could finally deliver a card that managed its own state across the lifespan of the poll.
On the interaction level, I also wanted to keep the card as minimal as possible, with a large, clear CTA. Since each poll card still needed two CTAs (one for each option) fitting independently both the copies and the two buttons in such a small piece of real estate made the UI really confusing. The solution to this problem turned out to be as easy as getting rid of the copy vs. button distinction, and merging them together, in a seamless experience.
The outcome is a poll card with larger tappable areas, since the poll container itself acts as the button, that creates a polarizing feeling through the color composition itself — which is the main idea behind the Would You Rather game. No additional buttons or text required, it is as simple as simple gets.
Before the refactor, code-wise, the poll card component was truly a mess. It consisted mainly of the poll text, then it had “attached” its correspondent CTA, which rendered dynamically depending on the poll state. What sounds like a plan on paper, caused a lot of problems since the CTAs had to manage its own state as well, turning the whole thing into a really confusing, inconsistent piece of code.
Following best practices, now the card has its own component during its lifecycle that properly manages the uniqueness of the poll throughout each step of the way. The components follow the SOLID principles and are isolated enough to do just one thing, but do it really well.
Material UI and styled-components
While from an engineering standpoint the most challenging tasks were by far the component refactors and the Redux integration, I also spent a fair amount of time moving away from the Material UI library in favor of custom-made components built with Styled Components.
The initial version of the project relied on the Material UI library for almost all UI facing components. Which on one hand was great because it provided well-established components straight out from Google’s Material UI toolkit, which inevitably led to faster development times. But on the other hand, it constrained the outcome to the Material UI look and feel, and worse, it handicapped the app’s performance since the library was huge.
I embarked on a laborious journey to refactor each component from scratch, removing its dependencies to the Material UI library, but most importantly, taking the time to ensure best practices were deployed across the app, making a clear distinction between presentational and container components.
Now presentational components are only concerned with how the app looks, are stateless, receive data and callbacks exclusively via props, and are written as functions.
Here’s where Styled Components really came in handy, allowing for the UI style to mutate depending on props and keeping the styles contained to each component. Really good stuff.
Final Thoughts
I could go on and on over many of the new features of the Would You Rather project. I really had a great time refactoring it from the ground up, but if you made it this far, I think it’d be a good idea for you to just go to the project repo and check it out for yourself.
From now on, I’ll try to be more incremental with its development, documenting the roadmap, properly adding issues to the project and working on it regularly, rather than doing massive, one-off pushes. The idea behind all this is no other than to keep practicing my coding skills, while building out things that could be of use to myself and (hopefully) others.
Next up, will be Flashcards, the third and final project of the Nanodegree: a mobile application built with React Native, that allows users to create decks, add cards with questions to the decks and, of course, quiz themselves and receive a score upon quiz completion.