All Projects → Gelio → Tslint React Hooks

Gelio / Tslint React Hooks

Licence: mit
TSLint rule for detecting invalid uses of React Hooks

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to Tslint React Hooks

Sonarts
Static code analyzer for TypeScript
Stars: ✭ 776 (+255.96%)
Mutual labels:  tslint, code-quality
TSLint.MSBuild
[Deprecated] An MSBuild task for running TSLint.
Stars: ✭ 13 (-94.04%)
Mutual labels:  tslint, code-quality
Jscpd
Copy/paste detector for programming source code.
Stars: ✭ 2,397 (+999.54%)
Mutual labels:  code-quality
Dotenv Linter
☺️ Linting dotenv files like a charm!
Stars: ✭ 207 (-5.05%)
Mutual labels:  code-quality
Codeclimate
Code Climate CLI
Stars: ✭ 2,273 (+942.66%)
Mutual labels:  code-quality
Parcel Plugin Typescript
🚨 Enhanced TypeScript support for Parcel
Stars: ✭ 176 (-19.27%)
Mutual labels:  code-quality
Gradle Baseline
A set of Gradle plugins that configure default code quality tools for developers.
Stars: ✭ 191 (-12.39%)
Mutual labels:  code-quality
Tslint Angular
Recommended tslint configuration for Angular applications.
Stars: ✭ 159 (-27.06%)
Mutual labels:  tslint
Code Review Checklist
This code review checklist helps you be a more effective and efficient code reviewer.
Stars: ✭ 214 (-1.83%)
Mutual labels:  code-quality
Flake8 Eradicate
Flake8 plugin to find commented out or dead code
Stars: ✭ 184 (-15.6%)
Mutual labels:  code-quality
Codestyle
JavaScript and TypeScript Style Guide
Stars: ✭ 207 (-5.05%)
Mutual labels:  tslint
Sonartsplugin
SonarQube plugin for TypeScript files
Stars: ✭ 182 (-16.51%)
Mutual labels:  tslint
Angular Tslint Rules
Shared TSLint & codelyzer rules to enforce a consistent code style for Angular development
Stars: ✭ 181 (-16.97%)
Mutual labels:  tslint
Angular2 Express Mongoose Gulp Node Typescript
AngularJS 2 (Updated to 4.2.0) Mean Stack application which uses Angular2, Gulp, Express, Node, MongoDB (Mongoose) with Repository Pattern Business Layer
Stars: ✭ 201 (-7.8%)
Mutual labels:  tslint
Infer
A static analyzer for Java, C, C++, and Objective-C
Stars: ✭ 12,823 (+5782.11%)
Mutual labels:  code-quality
Github Action
Coveralls Github Action
Stars: ✭ 214 (-1.83%)
Mutual labels:  code-quality
Express Graphql Typescript Boilerplate
A starter kit for building amazing GraphQL API's with TypeScript and express by @w3tecch
Stars: ✭ 163 (-25.23%)
Mutual labels:  tslint
Typescript Webpack React Redux Boilerplate
React and Redux with TypeScript
Stars: ✭ 182 (-16.51%)
Mutual labels:  tslint
Tslint Language Service
TypeScript 2.2.1 plugin for tslint
Stars: ✭ 190 (-12.84%)
Mutual labels:  tslint
Flakehell
Flake8 wrapper to make it nice, legacy-friendly, configurable.
Stars: ✭ 217 (-0.46%)
Mutual labels:  code-quality

TSLint Rules of Hooks

Downloads badge Version badge License badge GitHub stars badge Build Status

Demo

A TSLint rule that enforces the Rules of Hooks for React hooks.

The rule is based on an ESLint plugin for react hooks.

Features

  • detects using React hooks inside potentially-conditional branches:
    • if statements
    • short-circuit conditional expressions (&&, ||)
    • ternary expressions
    • loops (while, for, do ... while)
    • functions that themselves are not custom hooks or components
  • detects using React hooks in spite of an early return
  • support for detecting hooks from namespaces other than React (e.g. MyHooks.useHook) (optional)

Installation

First, install the rule:

npm install tslint-react-hooks --save-dev

Then, enable the rule by modifying tslint.json:

{
  "extends": [
    // your other plugins...
    "tslint-react-hooks"
  ],
  "rules": {
    // your other rules...
    "react-hooks-nesting": "error"
  }
}

To use report rule violations as warnings intead of errors, set it to "warning".

Options

While the rule works fine out-of-the-box, it can be customized. To specify options, use the following syntax when modifying tslint.json:

{
  "extends": [
    // your other plugins...
    "tslint-react-hooks"
  ],
  "rules": {
    // your other rules...
    "react-hooks-nesting": {
      "severity": "error", // "error", "warning", "default" or "off"
      "options": {
        // options go here
      }
    }
  }
}

Available options

  • "detect-hooks-from-non-react-namespace" - when set to true, violations will be also reported hooks accessed from sources other than the React namespace (e.g. MyHooks.useHook will be treated as a hook).

    By default, only direct calls (e.g. useHook) or calls from React namespace (e.g. React.useState) are treated as hooks.

Have an idea for an option? Create a new issue.

Workarounds

For some arrow functions/function expressions, the rule has no way to determine whether those are a component, a hook, both of which could contain hook calls, or a regular function that should not contain hook calls.

const withHoc = <TProps extends object>(Component: ComponentType<TProps>) => (
  props: TProps,
) => {
  const [state] = useState();
  return <Component {...props} />;
};

The workaround in those cases is to use a named function expression:

const withHoc = <TProps extends object>(Component: ComponentType<TProps>) =>
  function WrappedComponent(props: TProps) {
    const [state] = useState();
    return <Component {...props} />;
  };

Naming the function like a component (in PascalCase) unambiguously lets the rule treat the function as a component.

False positives and not-covered cases

There are some cases that seem hard to analyze and may result in false positives or false negatives.

In such cases, disable the rule for a specific line using the following comment:

// tslint:disable:react-hooks-nesting
useEffect(() => {});

Looping over static arrays

The rule may report false positives, for example in:

function MyComponent() {
  const array = [1, 2, 3];

  array.forEach(value => {
    React.useEffect(() => console.log(value));
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [A hook cannot be used inside of another function]
  });
}

The useEffect hook will be called unconditionally and the call-order will be the same between renders.

Using renamed hooks (that do not start with use)

The rule only treats functions that start with use as hooks. Therefore, renaming the hook will result in avoiding the rule:

const renamedUseState = React.useState;

function MyComponent() {
  const [state, setState] = renamedUseState(0);
}

Unconditional nesting

Unconditional nesting, for example:

function MyComponent() {
  if (true) {
    const variableThatCannotBeLeaked = useContext(SomeContext);
    useEffect(() => {
      console.log(variableThatCannotBeLeaked);
    });
  }

  return <div>Text</div>;
}

is treated as conditional nesting. It seems hard to verify if the condition is in fact a constant, therefore such a situation will always result in a rule violation.

In situations where such an if statement was used to create an additional block scope, use the block scope directly:

function MyComponent() {
  {
    const variableThatCannotBeLeaked = useContext(SomeContext);
    useEffect(() => {
      console.log(variableThatCannotBeLeaked);
    });
  }

  return <div>Text</div>;
}

Development

After pulling the repository, make sure to run

npm install

The source code for the rule is located in the src directory.

For more information about the developing custom TSLint rules, take a look at TSLint's documentation.

Testing the rule

Run

npm run test

to compile the rule and run automatic TSLint tests.

They are located in the test directory.

Author

The author of this rule is Grzegorz Rozdzialik.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].