WhoBuilt

Reducing bugs in a React codebase

Sep 26, 2022· 12 min· 784 views·Watch on YouTube

Speaker

Darshita Chaturvedi, co-founder and CEO of R3 Labs, which builds the A3 full-stack web framework, explains how her team reduces bugs in a React codebase at React Native EU 2022, hosted by Callstack.

Why bugs need guardrails

A3 lets users build websites with a visual editor or React on the front end and Python on the backend. Because one page can contain many interactions, a code issue in one interaction can affect the wider application. Chaturvedi describes three recurring problems: components that fail to update, update only partly, or render unexpectedly.

Make dependencies visible

Chaturvedi’s team first debugged recurring issues with print statements and React and browser DevTools, but found that approach too slow for rapid feature development. Their guiding principle is to make code independent of component render order and timing. When code dependencies are unclear, hooks such as `useState` and `useRef` without dependency arrays deserve extra scrutiny.

Choose the right update pattern

In an article viewer example, selecting an article should update its text, calculate a character count from its title and body, then fetch an emoji based on that count. Initializing state from props with `useState` leaves the count stale, so the request does not run. Giving the component an article ID as its key forces it to be destroyed and recreated, which updates the results but causes flicker.

Compute derived values without extra renders

Using `useEffect` with props as a dependency fixes the stale count without flicker, but causes an extra render after each prop change. Chaturvedi’s preferred approach is to compute the count with `useMemo`, which avoids that extra render. After refactoring, the framework averaged 0.35 `useState` calls per component across 112 custom hooks and 192 components.

Reduce state and avoid deep nesting

A slider refactor replaces four `useState` calls and three callbacks with no `useState` calls and one callback, using the callback’s local context to track interaction and making the component controlled. Chaturvedi says controlled components can be preferable when a page has many interactions. She also cautions that nested components can duplicate state and make changes harder to trace, so each piece of state should have a single source of truth.

Takeaways

  • Use `useMemo` for values derived from props when it avoids storing duplicate state and triggering an extra render.
  • Treat state initialized from props as a one-time value; choose a dependency-aware update pattern when inputs change.
  • Use component keys for identity changes deliberately, since destroying and recreating a component also resets its hooks and state.
  • Keep one source of truth for each piece of state to reduce inconsistencies and debugging effort.
  • For interaction-heavy pages, consider controlled components and keep interaction state local where practical.

Mentioned in this talk

Search inside this talk

What was claimed 8

  • built
    “the company behind this project”
    YouTube
    Unverified1 source· Talk
  • role at
    Darshita Chaturvedi is maintainer at A3
    “I am the maintainer of the open-source project A3”
    YouTube
    Unverified1 source· Talk
  • role at
    Darshita Chaturvedi is co-founder and CEO at R3 Labs
    “I am also the co-founder and CEO of R3 Labs”
    YouTube
    Unverified1 source· Talk
  • feature
    A3: Full-stack web development framework with a visual editor or React front end and a Python backend
    “the front end of a website can be created using a visual editor or by writing React code, while its backend can be written in Python”
    YouTube
    Unverified1 source· Talk
  • feature
    React DevTools: Used to investigate and fix bugs
    “random print statements, React DevTools, and browser DevTools to fix these bugs”
    YouTube
    Unverified1 source· Talk
  • feature
    useMemo: Derives the total character count from dependencies and avoids an extra render
    “moved the total character count computation to the useMemo hook, and thus we are able to prevent an extra render”
    YouTube
    Unverified1 source· Talk
  • metric
    A3: 0.35 useState calls per component
    “Our current status is at 0.35”
    YouTube
    Unverified1 source· Talk
  • metric
    A3: 112 custom hooks and 192 components
    “it has 112 custom hooks and 192 components”
    YouTube
    Unverified1 source· Talk

Related talks