Wednesday, January 9, 2019

You might have zombie React components lurking around your app


import React from "react";

class Cat extends React.Component {
    render() {
        if (this.props.cat.color === COLORS.BLACK) {
            return null;
        }
        return <p> {`Colorful ${this.props.cat.name}!`} </p>;
    }
}

What does this snippet return when used as a React component inside an app?

Well if the cat is of a black color, you won't see anything, not even an empty DOM node. But if you open your React devtools and peek at it, you're going to see this

<Cat/>

This is a full grown react component, it has its own copy of props, maintains its own state and responds to lifecycle methods. Worse, this component can cause crashes if you return null because the absence of a prop does not make sense in render, and consequently doesn't make sense in other lifecycle methods. This means if you don't pay attention to every lifecycle method, your app is gonna go boom. I've see that happen.

This is a waste of memory and CPU cycles and doesn't offer value for your app.

This doesn't mean you shouldn't ever do this. Components like this can make much sense in certain contexts. Rather, what I'm saying here is to be aware of the fact that they are still components in the React component hierarchy even though they are not really rendered.


The takeaways

  • Pay attention for dead React components in your app.
  • Whenever you don't want a component to render under a certain condition, always prefer checking for that condition in its parent.
  • When iterating over an list of data to map it to components, it's even better to filter the data before sending it to the component.
  • If you find yourself in a situation where you have to do this, prefer functional components over class components.