Sonarqube counts incorrect cognitive complexity for React Functional Components [BUG/NO FUNCTIONALITY]

In our application, we’ve implemented react components as “functional components”. This is a modern approach. But sonarqube thinks that react component is a “simple” function, and shows us the error regarding the “cognitive complexity”. Sonarqube should handle functions that are nested within a react component as isolated. If components are written as “class components” we won’t have such issues. * Community Edition * Version 7.9.2

function ChatBoardComponent(props: ChatBoardComponentProps) {
    
    function handleShowAddRoomModal() {
        if(something){
            do something
    }

    function handleCloseAddRoomModal() {
        if(something){
            do something
    }

    function handleSomethingElse() {
        if(something){
            do something
    }
    
    return <p>Hello world</p>;
}

Cognitive complexity for ChatBoardComponent component will be 6 (if I’m not mistaken). But I expect sonarqube to count cognitive complexity only for nested functions handleShowAddRoomModal, handleCloseAddRoomModal, handleSomethingElse. I mean if I wrote ChatBoardComponent component as class component sonar will count cognitive complexity only for the class “methods”. How can I tell sonarqube chat ChatBoardComponent it’s a react functional component and obey it re-count correctly?

2 Likes

Hi,

We gave a lot of though to how to handle this part of JavaScript. Here’s an excerpt from the whitepaper:

Despite the recent addition of classes to JavaScript by the ECMAScript 6 specification, the feature is not yet widely adopted. In fact, many popular frameworks require the continued use of the compensating idiom: the use of an outer function as a stand-in to create a kind of namespace or faux class. So as not to penalize JavaScript users, such outer functions are ignored when they are used purely as a declarative mechanism, that is when they contain only declarations at the top level.

However, the presence at the top level of a function (i.e. not nested inside a sub-function) of statements subject to structural increments indicates something other than a pure declarative usage. Consequently, such functions should receive a standard treatment.

So it’s the presence of your return <p>Hello world</p>; that’s causing this to be treated not as a class but as a standard function.

 
HTH,
Ann

Having a React functional component return the html to be rendered is the pattern of React functional components. It seems like Vladislav’s initial bug report is still correct. A functional component’s return value is equivalent to the render function in the traditional React Component class.
See step 1 here: https://www.digitalocean.com/community/tutorials/five-ways-to-convert-react-class-components-to-functional-components-with-react-hooks#step-1-—-understanding-a-class-without-state-or-lifecycle-methods
The cognitive complexity calculation should result in the same number for the ExampleClassComponent.js and the ExampleFunctionalComponent.js in the link I posted above. I’ll add the JavaScript here for posterity:

ExampleClassComponent.js

import React, { Component } from 'react';

class App extends Component {
  alertName = () => {
    alert('John Doe');
  };

  render() {
    return (
      <div>
        <h3>This is a Class Component</h3>
        <button onClick={this.alertName}>
          Alert
        </button>
      </div>
    );
  }
};

export default App;

ExampleFunctionalComponent.js

import React from 'react';

function App() {
  const alertName = () => {
    alert('John Doe');
  };

  return (
    <div>
      <h3>This is a Functional Component</h3>
      <button onClick={alertName}>
        Alert
      </button>
    </div>
  );
};

export default App;
4 Likes

Its a standard function as an alternate to es6 class . so despite the recent addition of class, the newer react code doesnt use class. it uses a function. however code written using class doesnt have this problem. and functional components have got this incorrect calculation. The argument is that the both styles of writing a component should lead to same complexity.

"So as not to penalize JavaScript users, such outer functions are ignored " hence , you should also treat the functional components in a similar way ( ignore it)

1 Like

I created ticket to add an exception for React components, you can follow it here.

2 Likes

Has there been any progress made on this issue regarding functional components? It seems this was on a release roadmap, and has constantly been shifted further until it was disregarded entirely.