WhoBuilt

Getting Better All the Time: How to Escape Bad Code

Sep 21, 2022· 31 min· 1.0K views·Watch on YouTube

Speaker

Principal architect Josh Justice of Big Nerd Ranch explains how to escape difficult code through small, test supported refactors at React Native EU 2022, hosted by Callstack.

A difficult restaurant list

Justice shows a restaurant list where adding has a loading state but deleting does not. Its 150 line component mixes unclear state names, nested JSX, inline asynchronous handlers, and styles. Those choices make it hard to add a separate deleting state for each row.

Why small refactors help

Justice defines bad code as code that makes a needed change difficult. Working around it can make later changes slower, while a full rewrite is a large commitment that may conflict with urgent fixes. With trusted tests, he instead extracts handlers, renames variables, and moves each restaurant row into its own component, then adds row level deleting state.

Tests support safe change

Justice describes refactoring as small changes to code structure that preserve behavior, checked by running tests after each step. Small changes can deliver value during ordinary feature work, and each step can be shipped if priorities change. TypeScript catches structural mistakes, but tests also check runtime behavior.

Build confidence with TDD

Justice presents test driven development as writing a failing test, adding enough code to pass it, then refactoring. His restaurant list example starts with tests for displayed names, errors, and loading states, adding tests for when messages should be absent before implementing those conditions. He says the tests need to cover behavior well enough to support future changes.

Make code better as you work

Justice argues that TDD’s biggest benefit is giving developers confidence to refactor continuously. He acknowledges that TDD takes effort, while living with difficult code also carries ongoing costs. His goal is a codebase whose tests let developers adapt the code to new requirements, even when the existing structure is poor.

Takeaways

  • Use feature work as an opportunity to improve the code you touch through small refactors.
  • Run trusted behavior tests after each structural change to catch regressions early.
  • Extract repeated list rows into components when each row needs its own state.
  • Test both when a message appears and when it should be absent.
  • Use TypeScript for structural checks and runtime tests for behavior confidence.

Mentioned in this talk

Search inside this talk

What was claimed 5

  • works at
    “I work at Vigneron Ranch.”
    YouTube
    Unverified1 source· Talk
  • feature
    RestaurantRow: Holds per-row deleting state and displays a deleting state while deletion is in progress
    “Now that we have a RestaurantRow component, it’s a convenient place to put the state for deleting.”
    YouTube
    Unverified1 source· Talk
  • feature
    TDD: Uses a three-step cycle: write a failing test, write enough code to pass, then refactor
    “Step one is to write a test and see it fail for the new functionality. Step two is to write just enough code to make the test pass. In step three, you refactor.”
    YouTube
    Unverified1 source· Talk
  • feature
    Big Nerd Ranch: Builds apps with React Native, native iOS and Android, and web apps; provides corporate training
    “We build apps with React Native, native iOS and Android, and web apps as well. We also do corporate training.”
    YouTube
    Unverified1 source· Talk
  • role at
    Josh Justice is principal architect at Big Nerd Ranch
    “I'm a principal architect at Big Nerd Ranch.”
    YouTube
    Unverified1 source· Talk

Related talks