Blog post

Lesser spotted React mistakes: Zombie methods

Gabriel Vivas

Product Manager

4 min read

  • SonarCloud
  • SonarLint
  • SonarQube
  • TypeScript
  • JavaScript
  • React
  • ESLint

This series is dedicated to the small, but common pitfalls and errors you can encounter when writing React code. Whether an experienced JavaScript | TypeScript developer or just starting out, the results can be surprising.


These are the kind of issues you want to catch early in your IDE before you spend hours debugging. You can copy/paste the code examples in VS Code with the free SonarLint plugin if you want to see them for yourself and try to catch them before they happen to you!

Part 2: Zombie methods

This second installment of the series is all about low-effort references to George Romero and ancient Papua New Guinea cuisine.


More seriously, we’ll talk about code that is redundant or never executed and how it can hinder your work. Getting into React’s entrails, we’ll discuss how undead code may signal questionable code architecture 😵.

🪦 Dead code is dragging you down

When code is not being used, we call it “dead code”. We want to avoid dead code because it gets in the way. The only thing that it is doing is taking up mental effort when you are trying to read the code that matters. Dead code consumes our brains 🍽️ 🧠.


When you suspect some method is not being used, here’s one old trick: run a project-wide code search for the method name. If the only mention of the method name in the whole codebase is the definition… you’re likely dealing with some life-less bytes ⚰️.


Dead code can also be a significant error, for example, when you make a small typo. It can obscure bugs. We won’t go into that here. That’s a topic for another day.


Anyway, check this example below:

import React, { Component } from 'react';

export default class Profile extends Component {
  getDefaultName() {
    return 'John Smith';
  }

  render(props) {
    return (<h1>{props.name}</h1>);
  }
}

As you can tell, the method getDefaultName is not being used.


That was easy, but still, you caught that one 💪. Of course, it can be much harder to find dead code when you have many more methods and logic in your components.


That is when you feel happy about having SonarLint installed 🦾, because it will pick up this issue instantly. You also get some prose to help you make sense of it.


See the picture below or click here for an expanded view:

In case you’re wondering, there is an Eslint rule that can help with unused methods in React components. You’ll need to enable it in your configuration since it is not present in the default set of rules:

$ npm install eslint eslint-plugin-react --save-dev

$ cat .eslintrc.json
{
  "extends": [
    "plugin:react/recommended"
  ],
  "rules": {
    "react/no-unused-class-component-methods": "error"
  }
}

You might be thinking:


“Wait a minute. That's all nice. But how can you be sure the method is not being used dynamically with a property accessor by passing a computed string before invoking it, eh?”


Wow, you’re hypothetically smart. And also right.


Indeed, JavaScript and TypeScript are dynamic. As it happens, somebody might have introduced some carefully crafted conjuring 🧙✨. It is quite hard to tell if the program is actually using all the code or not.


This is why SonarLint is modest and takes a different approach that happens to solve a more interesting problem. Wait for it…

Undead code. When it smells bad 👃, it’s probably…

A word that rhymes with bad. Sad! Mad! Cat? Nevermind, cats are fine 🐈


Confusing is the word. This is going to be confusing. Because it does not rhyme.


Let's talk about Component methods that appear to be dead code, when they are actually undead, like the red-leathered king of pop in that spooky thriller!

For something less artful and scarier, imagine you see a method in your component that is not being called anywhere in the file. A head-scratcher.


You think, “Hey, this reminds me of that cheeky article at the Sonar blog 🐋”.


And you’re ready to clean that dead code 🔪.


Precautious as you are, you run a project-wide search for the method name, and then, there it is, the method is being called from a different Component. Not dead. Undead 🧟.


Let’s see an example:

import React, { Component } from "react";

export default class Cowsay extends Component {
  constructor(props) {
    super(props);
    this.state = { text: "Hello world!" };
  }

  componentDidMount() {
    this.props.onMounted(this);
  }

  say(text) {
    this.setState({ text });
  }

  render() {
    return <pre>{this.state.text}</pre>;
  }
}

That Component sure looks strange. Smelly, you might say. If it smells bad, it’s probably… not a cat 🐈.


For sure, nobody would do something like that 😧! How would you even call say()?


See the rest of the code below:

import React, { Component } from "react";
import Cowsay from “./Cowsay”;

class MadCowDisease extends Component {
  render() {
    return (
      <div>
        <Cowsay onMounted={(cow) => (this.cow = cow)} />
        <button onClick={() => this.cow.say("Moo!")}>Say Moo!</button>
      </div>
    );
  }
}

(Credits to StackOverflow user @gitaarik for this funky example which we shortened for brevity.)


What? That should not be possible, right? Try it in VSCode!


This is where you start to see the relationship between eating brains and mad cow disease.


Or perhaps you see no problem in calling methods from outside the Component 🧙✨.


Truth is, there are many ways to do this. Some of them might look less disturbing. But they are all at the edge of React’s philosophy.


Even if we are using the class syntax, instances of components are not supposed to communicate via methods and state. React embraces a functional paradigm and expects you to use props and children to pass information around. Component state should remain an internal affair.


When you are faced with a situation where you feel tempted to dig into the guts of a Component to reach its state or something else, you probably need to lift your state.


React Component methods that are not used inside the Component should be dead code.


If they are undead, you know what to do 🔪🧟.


This is why your friendly SonarLint will raise an issue if you happen to sway too much into the undead zone. It won’t play the music, but from now on you can hear it in your head 🎵.

Prevent issues before they happen

We hope you had fun reading and trying the code snippets in your IDE. Undead code is out there! As you’ve seen it is more dangerous than dead code 🪦.


By default, SonarLint will detect all these issues and warn you as they come up, so you can fix them on the spot, without losing focus. If you want to dig deeper, SonarLint will also provide an explanation in the rule description, as to why it happens in the first place.


Did we mention that SonarLint is free and Open Source?

Next up: “Part 3: Render what?”

In the next installment, we’ll look at subtle defects you could inadvertently introduce when rendering React components. Smell ya’ later 🐋!


If you liked this post, send us a Tweet @SonarSource or a comment in the Community. We’d love to hear about your experience.


Read more about this rule in our catalog:


S6441 Unused methods of React components should be removed


Previous posts:


Part 1 of "Lesser spotted React mistakes": Hooked on a feeling

  • Follow SonarSource on Twitter
  • Follow SonarSource on Linkedin

© 2008-2023, SonarSource S.A, Switzerland. All content is copyright protected. SONAR, SONARSOURCE, SONARLINT, SONARQUBE and SONARCLOUD are trademarks of SonarSource SA. All other trademarks and copyrights are the property of their respective owners. All rights are expressly reserved.