Skip to content

isHookCall doesn't detect namespace hook calls (React.useState, React.useEffect, etc.) #117

@Akshay090

Description

@Akshay090

Bug

isHookCall only checks node.callee?.type === "Identifier" — it never handles MemberExpression (React.useEffect).

Current implementation

const isHookCall = (node, hookName) =>
  node.type === "CallExpression" &&
  node.callee?.type === "Identifier" &&
  (typeof hookName === "string"
    ? node.callee.name === hookName
    : hookName.has(node.callee.name));

This only matches direct calls like useEffect(...) where the callee is an Identifier. It does not match React.useEffect(...) where the callee is a MemberExpression ({ object: { name: "React" }, property: { name: "useEffect" } }).

Impact

Every rule that uses isHookCall silently misses namespace-style hook calls. This affects:

  • no-derived-state-effect
  • no-fetch-in-effect
  • no-cascading-set-state
  • no-effect-event-handler
  • and others

Additionally, isSetterIdentifier checks inside rule bodies only match Identifier callee types, missing React.useState setter patterns (e.g. in countSetStateCalls, noDerivedStateEffect, rerenderFunctionalSetstate, renderingHydrationNoFlicker).

Steps to reproduce

// DETECTED (named import)
import { useState, useEffect } from 'react';
const [label, setLabel] = useState('');
useEffect(() => { setLabel(`${value}-x`); }, [value]);

// NOT DETECTED (namespace import — very common pattern)
import * as React from 'react';
const [label, setLabel] = React.useState('');
React.useEffect(() => { setLabel(`${value}-x`); }, [value]);

Run npx react-doctor . --verbose on each — only the named import version flags no-derived-state-effect.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions