when I add this check:
card.targetUrl !== "/test"
I get this error and I cannot commit, how do I reduce this complexity?
const link = useMemo(() => {
if (!card?.targetUrl || card.targetUrl === "/test") {
return "/account";
} else {
return card.targetUrl;
}
}, [card]);
this error is not present when the code looks like this:
const link = useMemo(() => {
if (card?.targetUrl) {
return card.targetUrl;
} else {
return "/account";
}
}, [card]);
3
Answers
Cognitive Complexity can be defined as "a measure of how difficult a unit of code is to intuitively understand".
To me, the intent of your code as it is now is not very obvious, since I need to mentally compute the null check, the negation, the
or
and the equality on the right side. Doesn’t seem like much when we’re writing it, but others (and even you later) might find it difficult to read, hence the high cognitive complexity score.I have some suggestions for you in order to make it simpler to understand:
Have each condition in a separate
if
clause:Some people might be hesitant to repeat the same return value (remember DRY?), but making your code easier to read and easier to change makes it worthwhile. For instance, maybe you’ll want to remove the
card.targetUrl === "/test"
condition at a later time, in the sample code above it would be easy because they’re separate.Don’t use the
else
keyword.Since your code is doing early returns, the
else
clause is not needed. This advice comes from Object Calisthenics, check it out.If you don’t want to repeat returns, there’s another way to make the code more readable by extracting the condition into a new function and giving it a descriptive name (pardon my rusty Javascript):
Cognitive complexity is increased when there are breaks in the linear flow of control.
if
,else
blocks and early returns may increase it. You can remove one inner block and the early returns by initialising a variable with the default value, like this:Just remove useMemo. It takes more CPU time than calculations inside of it.
const link = !card || card.targetUrl === "/test" ? "/account" : card.targetUrl
with useMemo each render you have to create a functuion, get previously stored dependencies, loop through it, and even if there were no changes you already spent ten times more CPU time that simple string compare.
And if card was chnaged, then… uhh. execute the function, store return value somewhere, replace dependencies.. ohh.. and store hook into hook execution chain… I believe even more overhead is here.