@codelaw/rules-react 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +23 -0
- package/NOTICE +10 -0
- package/README.md +50 -2
- package/codelaw-pack.toml +6 -0
- package/corpus.toml +25 -0
- package/data/react/dom-property-aliases.json +131 -0
- package/package.json +14 -4
- package/presets/react/conventions.toml +5 -0
- package/presets/react/recommended.toml +22 -0
- package/rules/react/display-name.md +91 -0
- package/rules/react/exhaustive-deps.md +116 -0
- package/rules/react/hook-prefix.md +108 -0
- package/rules/react/jsx-key.md +99 -0
- package/rules/react/jsx-no-comment-textnodes.md +87 -0
- package/rules/react/jsx-no-duplicate-props.md +66 -0
- package/rules/react/jsx-no-target-blank.md +78 -0
- package/rules/react/jsx-no-undef.md +78 -0
- package/rules/react/no-children-prop.md +80 -0
- package/rules/react/no-danger-with-children.md +83 -0
- package/rules/react/no-deprecated.md +84 -0
- package/rules/react/no-direct-mutation-state.md +102 -0
- package/rules/react/no-find-dom-node.md +72 -0
- package/rules/react/no-is-mounted.md +109 -0
- package/rules/react/no-render-return-value.md +75 -0
- package/rules/react/no-string-refs.md +72 -0
- package/rules/react/no-unescaped-entities.md +69 -0
- package/rules/react/no-unknown-property.md +69 -0
- package/rules/react/props-type-name.md +43 -0
- package/rules/react/require-render-return.md +91 -0
- package/rules/react/rules-of-hooks.md +128 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: react/rules-of-hooks
|
|
3
|
+
title: "Hooks are called at the top level of components and hooks"
|
|
4
|
+
languages: [javascript, jsx, typescript, tsx]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "moving a hook can change what the code does on the renders that skipped it"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [eslint-plugin-react-hooks/rules-of-hooks]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Hooks (`useState`, `useEffect`, any `use…`) are called only at the top level of a function component
|
|
13
|
+
or a custom hook: not in conditions, loops, nested functions, after an early return, in classes, or
|
|
14
|
+
in plain functions.
|
|
15
|
+
|
|
16
|
+
**Why:** React matches hook calls to state by their order, so a hook that runs on some renders and
|
|
17
|
+
not others mixes up every hook after it.
|
|
18
|
+
|
|
19
|
+
```codelaw
|
|
20
|
+
native: react/rules-of-hooks
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## How to fix
|
|
24
|
+
|
|
25
|
+
1. Move the hook call to the top level of the component or hook, before any early return.
|
|
26
|
+
2. Put the condition inside the hook (e.g. inside the effect) instead of around it.
|
|
27
|
+
|
|
28
|
+
## Examples
|
|
29
|
+
|
|
30
|
+
### JavaScript
|
|
31
|
+
|
|
32
|
+
#### Don't
|
|
33
|
+
|
|
34
|
+
```js
|
|
35
|
+
function Profile({ id }) {
|
|
36
|
+
if (!id) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const [user] = useState(null);
|
|
40
|
+
return user;
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
#### Do
|
|
45
|
+
|
|
46
|
+
```js
|
|
47
|
+
function Profile({ id }) {
|
|
48
|
+
const [user] = useState(null);
|
|
49
|
+
if (!id) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
return user;
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### JSX
|
|
57
|
+
|
|
58
|
+
#### Don't
|
|
59
|
+
|
|
60
|
+
```jsx
|
|
61
|
+
function Profile({ id }) {
|
|
62
|
+
if (!id) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
const [user] = useState(null);
|
|
66
|
+
return user;
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
#### Do
|
|
71
|
+
|
|
72
|
+
```jsx
|
|
73
|
+
function Profile({ id }) {
|
|
74
|
+
const [user] = useState(null);
|
|
75
|
+
if (!id) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
return user;
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### TypeScript
|
|
83
|
+
|
|
84
|
+
#### Don't
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
function useProfile(id: string) {
|
|
88
|
+
if (!id) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
return useState(id);
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### Do
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
function useProfile(id: string) {
|
|
99
|
+
const state = useState(id);
|
|
100
|
+
return id ? state : null;
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### TSX
|
|
105
|
+
|
|
106
|
+
#### Don't
|
|
107
|
+
|
|
108
|
+
```tsx
|
|
109
|
+
function Profile({ id }) {
|
|
110
|
+
if (!id) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
const [user] = useState(null);
|
|
114
|
+
return user;
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### Do
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
function Profile({ id }) {
|
|
122
|
+
const [user] = useState(null);
|
|
123
|
+
if (!id) {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
return user;
|
|
127
|
+
}
|
|
128
|
+
```
|