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.

@arevi , you are right this was postponed for too long, we’ve been caught with other things with higher priority. We will try to handle it in the next cycle.

@saberduck Any ETA? Just wanted to add that we’re also tracking this.

Ticket is fixed in js analyzer, which is already deployed on SonarCloud and will be part of SQ 9.0 (will be released in july).

Hello,
Now that SQ 9 is available, is there any confirmation that this issue has been resolved successfully?

1 Like

@Reggie_Johnson , yes the fix was shipped with SQ 9.0

1 Like

@saberduck thank you for the confirmation

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.