Repository: facebook/react
File: packages/eslint-plugin-react-hooks/src/rules/ExhaustiveDeps.ts (TypeScript)

Code before:
      const reactiveHook = node.callee;
      const nodeWithoutNamespace = getNodeWithoutReactNamespace(reactiveHook);
      const reactiveHookName =
        'name' in nodeWithoutNamespace ? nodeWithoutNamespace.name : '';
      const maybeNode = node.arguments[callbackIndex + 1];
      const declaredDependenciesNode =
        maybeNode &&
        !(maybeNode.type === 'Identifier' && maybeNode.name === 'undefined')
          ? maybeNode
          : undefined;
      const isEffect = /Effect($|[^a-z])/g.test(reactiveHookName);

      // Check whether a callback is supplied. If there is no callback supplied
      // then the hook will not work and React will throw a TypeError.
      // So no need to check for dependency inclusion.
      if (!callback) {
        reportProblem({
          node: reactiveHook,
          message:
            `React Hook ${reactiveHookName} requires an effect callback. ` +
            `Did you forget to pass a callback to the hook?`,
        });
        return;
      }

      // use(Layout)BarcelonaEffect is a special case which allows null as the equivalent of useEffect with no array.
      if (
        !declaredDependenciesNode ||
        (options.experimental_effectHooksWithNullDependenciesAllowed.includes(
          reactiveHookName,
        ) &&
          declaredDependenciesNode.type === 'Literal' &&
          declaredDependenciesNode.value === null)
      ) {
        return;
      }

      // Check the declared dependencies for this reactive hook. If there is no
      // second argument then the reactive callback will re-run on every render.
      // So no need to check for dependency inclusion.
      if (!declaredDependenciesNode && !isEffect) {
        // These are only used for optimization.
        if (
          reactiveHookName === 'useMemo' ||
          reactiveHookName === 'useCallback'
        ) {
          // TODO: Can this have a suggestion?
          reportProblem({
            node: reactiveHook,
            message:
              `React Hook ${reactiveHookName} does nothing when called with ` +

Review comment (suggestion):
```suggestion
      // special case which allows null as the equivalent of useEffect with no array.
```

Code after:

    function visitCallExpression(node: CallExpression): void {
      const callbackIndex = getReactiveHookCallbackIndex(node.callee, options);
      if (callbackIndex === -1) {
        // Not a React Hook call that needs deps.
        return;
      }
      let callback = node.arguments[callbackIndex];
      const reactiveHook = node.callee;
      const nodeWithoutNamespace = getNodeWithoutReactNamespace(reactiveHook);
      const reactiveHookName =
        'name' in nodeWithoutNamespace ? nodeWithoutNamespace.name : '';
      const maybeNode = node.arguments[callbackIndex + 1];
      const declaredDependenciesNode =
        maybeNode &&
        !(maybeNode.type === 'Identifier' && maybeNode.name === 'undefined')
          ? maybeNode
          : undefined;
      const isEffect = /Effect($|[^a-z])/g.test(reactiveHookName);

      // Check whether a callback is supplied. If there is no callback supplied
      // then the hook will not work and React will throw a TypeError.
      // So no need to check for dependency inclusion.
      if (!callback) {
        reportProblem({
          node: reactiveHook,
          message:
            `React Hook ${reactiveHookName} requires an effect callback. ` +
            `Did you forget to pass a callback to the hook?`,
        });
        return;
      }

      const isAutoDepsHook =
        options.experimental_autoDependenciesHooks.includes(reactiveHookName);

      // Check the declared dependencies for this reactive hook. If there is no
      // second argument then the reactive callback will re-run on every render.
      // So no need to check for dependency inclusion.
      if (
        (!declaredDependenciesNode ||
          (isAutoDepsHook &&
            declaredDependenciesNode.type === 'Literal' &&
            declaredDependenciesNode.value === null)) &&
        !isEffect
      ) {
        // These are only used for optimization.
        if (
          reactiveHookName === 'useMemo' ||
          reactiveHookName === 'useCallback'
        ) {