UNPKG

4.42 kBMarkdownView Raw
1# TSLint Rules of Hooks
2
3[![Downloads badge](https://img.shields.io/npm/dw/tslint-react-hooks.svg?style=flat)](https://www.npmjs.com/package/tslint-react-hooks)
4[![Version badge](https://img.shields.io/npm/v/tslint-react-hooks.svg?style=flat)](https://www.npmjs.com/package/tslint-react-hooks)
5[![License badge](https://img.shields.io/npm/l/tslint-react-hooks.svg?style=flat)](https://github.com/Gelio/tslint-react-hooks/blob/master/LICENSE.md)
6[![GitHub stars badge](https://img.shields.io/github/stars/Gelio/tslint-react-hooks.svg?style=social)](https://github.com/Gelio/tslint-react-hooks)
7[![Build Status](https://dev.azure.com/vorenygelio/vorenygelio/_apis/build/status/Gelio.tslint-react-hooks?branchName=master)](https://dev.azure.com/vorenygelio/vorenygelio/_build/latest?definitionId=3&branchName=master)
8
9![Demo](https://i.imgur.com/SGHlOvF.png)
10
11A TSLint rule that enforces the [Rules of Hooks](https://reactjs.org/docs/hooks-rules.html) for
12React hooks.
13
14The rule is based on an [ESLint plugin for react hooks](https://github.com/facebook/react/blob/master/packages/eslint-plugin-react-hooks/README.md).
15
16## Features
17
18- detects using React hooks inside potentially-conditional branches:
19 - if statements
20 - short-circuit conditional expressions (`&&`, `||`)
21 - ternary expressions
22 - loops (`while`, `for`, `do ... while`)
23 - functions that themselves are not custom hooks or components
24- detects using React hooks in spite of an early return
25
26## Installation
27
28First, install [the rule](https://www.npmjs.com/package/tslint-react-hooks):
29
30```sh
31npm install tslint-react-hooks --save-dev
32```
33
34Then, enable the rule by modifying `tslint.json`:
35
36```js
37{
38 "extends": [
39 // your other plugins...
40 "tslint-react-hooks"
41 ],
42 "rules": {
43 // your other rules...
44 "react-hooks-nesting": "error"
45 }
46}
47```
48
49To use report rule violations as warnings intead of errors, set it to `"warning"`.
50
51## False positives and not-covered cases
52
53There are some cases that seem hard to analyze and may result in false positives or false negatives.
54
55In such cases, disable the rule for a specific line using the following comment:
56
57```ts
58// tslint:disable:react-hooks-nesting
59useEffect(() => {});
60```
61
62### Looping over static arrays
63
64The rule may report false positives, for example in:
65
66```ts
67function MyComponent() {
68 const array = [1, 2, 3];
69
70 array.forEach(value => {
71 React.useEffect(() => console.log(value));
72 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [A hook cannot be used inside of another function]
73 });
74}
75```
76
77The `useEffect` hook will be called unconditionally and the call-order will be the same between
78renders.
79
80### Using renamed hooks (that do not start with _use_)
81
82The rule only treats functions that start with _use_ as hooks. Therefore, renaming the hook will
83result in avoiding the rule:
84
85```ts
86const renamedUseState = React.useState;
87
88function MyComponent() {
89 const [state, setState] = renamedUseState(0);
90}
91```
92
93### Unconditional nesting
94
95Unconditional nesting, for example:
96
97```tsx
98function MyComponent() {
99 if (true) {
100 const variableThatCannotBeLeaked = useContext(SomeContext);
101 useEffect(() => {
102 console.log(variableThatCannotBeLeaked);
103 });
104 }
105
106 return <div>Text</div>;
107}
108```
109
110is treated as conditional nesting. It seems hard to verify if the condition is in fact a constant,
111therefore such a situation will always result in a rule violation.
112
113In situations where such an `if` statement was used to create an additional block scope, use the
114block scope directly:
115
116```tsx
117function MyComponent() {
118 {
119 const variableThatCannotBeLeaked = useContext(SomeContext);
120 useEffect(() => {
121 console.log(variableThatCannotBeLeaked);
122 });
123 }
124
125 return <div>Text</div>;
126}
127```
128
129## Development
130
131After pulling the repository, make sure to run
132
133```sh
134npm install
135```
136
137The source code for the rule is located in the `src` directory.
138
139For more information about the developing custom TSLint rules, take a look at
140[TSLint's documentation](https://palantir.github.io/tslint/develop/custom-rules/).
141
142### Testing the rule
143
144Run
145
146```sh
147npm run test
148```
149
150to compile the rule and run automatic TSLint tests.
151
152They are located in the `test` directory.
153
154## Author
155
156The author of this rule is Grzegorz Rozdzialik.