1
+
2
+## Input
3
+
4
+```javascript
5
+// @validateExhaustiveMemoizationDependencies
6
+import {useMemo} from 'react';
7
+import {Stringify} from 'shared-runtime';
8
+
9
+function Component({x, y, z}) {
10
+ const a = useMemo(() => {
11
+ return x?.y.z?.a;
12
+ // error: too precise
13
+ }, [x?.y.z?.a.b]);
14
+ const b = useMemo(() => {
15
+ return x.y.z?.a;
16
+ // ok, not our job to type check nullability
17
+ }, [x.y.z.a]);
18
+ const c = useMemo(() => {
19
+ return x?.y.z.a?.b;
20
+ // error: too precise
21
+ }, [x?.y.z.a?.b.z]);
22
+ const d = useMemo(() => {
23
+ return x?.y?.[(console.log(y), z?.b)];
24
+ // ok
25
+ }, [x?.y, y, z?.b]);
26
+ const e = useMemo(() => {
27
+ const e = [];
28
+ e.push(x);
29
+ return e;
30
+ // ok
31
+ }, [x]);
32
+ const f = useMemo(() => {
33
+ return [];
34
+ // error: unnecessary
35
+ }, [x, y.z, z?.y?.a, UNUSED_GLOBAL]);
36
+ const ref1 = useRef(null);
37
+ const ref2 = useRef(null);
38
+ const ref = z ? ref1 : ref2;
39
+ const cb = useMemo(() => {
40
+ return () => {
41
+ return ref.current;
42
+ };
43
+ // error: ref is a stable type but reactive
44
+ }, []);
45
+ return <Stringify results={[a, b, c, d, e, f, cb]} />;
46
+}
47
+
48
+```
49
+
50
+
51
+## Error
52
+
53
+```
54
+Found 5 errors:
55
+
56
+Error: Found missing/extra memoization dependencies
57
+
58
+Missing dependencies can cause a value to update less often than it should, resulting in stale UI. Extra dependencies can cause a value to update more often than it should, resulting in performance problems such as excessive renders or effects firing too often.
59
+
60
+error.invalid-exhaustive-deps.ts:7:11
61
+ 5 | function Component({x, y, z}) {
62
+ 6 | const a = useMemo(() => {
63
+> 7 | return x?.y.z?.a;
64
+ | ^^^^^^^^^ Missing dependency `x?.y.z?.a`
65
+ 8 | // error: too precise
66
+ 9 | }, [x?.y.z?.a.b]);
67
+ 10 | const b = useMemo(() => {
68
+
69
+error.invalid-exhaustive-deps.ts:9:6
70
+ 7 | return x?.y.z?.a;
71
+ 8 | // error: too precise
72
+> 9 | }, [x?.y.z?.a.b]);
73
+ | ^^^^^^^^^^^ Overly precise dependency `x?.y.z?.a.b`, use `x?.y.z?.a` instead
74
+ 10 | const b = useMemo(() => {
75
+ 11 | return x.y.z?.a;
76
+ 12 | // ok, not our job to type check nullability
77
+
78
+Inferred dependencies: `[x?.y.z?.a]`
79
+
80
+Error: Found missing/extra memoization dependencies
81
+
82
+Missing dependencies can cause a value to update less often than it should, resulting in stale UI. Extra dependencies can cause a value to update more often than it should, resulting in performance problems such as excessive renders or effects firing too often.
83
+
84
+error.invalid-exhaustive-deps.ts:15:11
85
+ 13 | }, [x.y.z.a]);
86
+ 14 | const c = useMemo(() => {
87
+> 15 | return x?.y.z.a?.b;
88
+ | ^^^^^^^^^^^ Missing dependency `x?.y.z.a?.b`
89
+ 16 | // error: too precise
90
+ 17 | }, [x?.y.z.a?.b.z]);
91
+ 18 | const d = useMemo(() => {
92
+
93
+error.invalid-exhaustive-deps.ts:17:6
94
+ 15 | return x?.y.z.a?.b;
95
+ 16 | // error: too precise
96
+> 17 | }, [x?.y.z.a?.b.z]);
97
+ | ^^^^^^^^^^^^^ Overly precise dependency `x?.y.z.a?.b.z`, use `x?.y.z.a?.b` instead
98
+ 18 | const d = useMemo(() => {
99
+ 19 | return x?.y?.[(console.log(y), z?.b)];
100
+ 20 | // ok
101
+
102
+Inferred dependencies: `[x?.y.z.a?.b]`
103
+
104
+Error: Found missing/extra memoization dependencies
105
+
106
+Extra dependencies can cause a value to update more often than it should, resulting in performance problems such as excessive renders or effects firing too often.
107
+
108
+error.invalid-exhaustive-deps.ts:31:6
109
+ 29 | return [];
110
+ 30 | // error: unnecessary
111
+> 31 | }, [x, y.z, z?.y?.a, UNUSED_GLOBAL]);
112
+ | ^ Unnecessary dependency `x`
113
+ 32 | const ref1 = useRef(null);
114
+ 33 | const ref2 = useRef(null);
115
+ 34 | const ref = z ? ref1 : ref2;
116
+
117
+error.invalid-exhaustive-deps.ts:31:9
118
+ 29 | return [];
119
+ 30 | // error: unnecessary
120
+> 31 | }, [x, y.z, z?.y?.a, UNUSED_GLOBAL]);
121
+ | ^^^ Unnecessary dependency `y.z`
122
+ 32 | const ref1 = useRef(null);
123
+ 33 | const ref2 = useRef(null);
124
+ 34 | const ref = z ? ref1 : ref2;
125
+
126
+error.invalid-exhaustive-deps.ts:31:14
127
+ 29 | return [];
128
+ 30 | // error: unnecessary
129
+> 31 | }, [x, y.z, z?.y?.a, UNUSED_GLOBAL]);
130
+ | ^^^^^^^ Unnecessary dependency `z?.y?.a`
131
+ 32 | const ref1 = useRef(null);
132
+ 33 | const ref2 = useRef(null);
133
+ 34 | const ref = z ? ref1 : ref2;
134
+
135
+error.invalid-exhaustive-deps.ts:31:23
136
+ 29 | return [];
137
+ 30 | // error: unnecessary
138
+> 31 | }, [x, y.z, z?.y?.a, UNUSED_GLOBAL]);
139
+ | ^^^^^^^^^^^^^ Unnecessary dependency `UNUSED_GLOBAL`. Values declared outside of a component/hook should not be listed as dependencies as the component will not re-render if they change
140
+ 32 | const ref1 = useRef(null);
141
+ 33 | const ref2 = useRef(null);
142
+ 34 | const ref = z ? ref1 : ref2;
143
+
144
+Inferred dependencies: `[]`
145
+
146
+Error: Found missing/extra memoization dependencies
147
+
148
+Extra dependencies can cause a value to update more often than it should, resulting in performance problems such as excessive renders or effects firing too often.
149
+
150
+error.invalid-exhaustive-deps.ts:31:6
151
+ 29 | return [];
152
+ 30 | // error: unnecessary
153
+> 31 | }, [x, y.z, z?.y?.a, UNUSED_GLOBAL]);
154
+ | ^ Unnecessary dependency `x`
155
+ 32 | const ref1 = useRef(null);
156
+ 33 | const ref2 = useRef(null);
157
+ 34 | const ref = z ? ref1 : ref2;
158
+
159
+error.invalid-exhaustive-deps.ts:31:9
160
+ 29 | return [];
161
+ 30 | // error: unnecessary
162
+> 31 | }, [x, y.z, z?.y?.a, UNUSED_GLOBAL]);
163
+ | ^^^ Unnecessary dependency `y.z`
164
+ 32 | const ref1 = useRef(null);
165
+ 33 | const ref2 = useRef(null);
166
+ 34 | const ref = z ? ref1 : ref2;
167
+
168
+error.invalid-exhaustive-deps.ts:31:14
169
+ 29 | return [];
170
+ 30 | // error: unnecessary
171
+> 31 | }, [x, y.z, z?.y?.a, UNUSED_GLOBAL]);
172
+ | ^^^^^^^ Unnecessary dependency `z?.y?.a`
173
+ 32 | const ref1 = useRef(null);
174
+ 33 | const ref2 = useRef(null);
175
+ 34 | const ref = z ? ref1 : ref2;
176
+
177
+error.invalid-exhaustive-deps.ts:31:23
178
+ 29 | return [];
179
+ 30 | // error: unnecessary
180
+> 31 | }, [x, y.z, z?.y?.a, UNUSED_GLOBAL]);
181
+ | ^^^^^^^^^^^^^ Unnecessary dependency `UNUSED_GLOBAL`. Values declared outside of a component/hook should not be listed as dependencies as the component will not re-render if they change
182
+ 32 | const ref1 = useRef(null);
183
+ 33 | const ref2 = useRef(null);
184
+ 34 | const ref = z ? ref1 : ref2;
185
+
186
+Inferred dependencies: `[]`
187
+
188
+Error: Found missing/extra memoization dependencies
189
+
190
+Missing dependencies can cause a value to update less often than it should, resulting in stale UI.
191
+
192
+error.invalid-exhaustive-deps.ts:37:13
193
+ 35 | const cb = useMemo(() => {
194
+ 36 | return () => {
195
+> 37 | return ref.current;
196
+ | ^^^ Missing dependency `ref`. Refs, setState functions, and other "stable" values generally do not need to be added as dependencies, but this variable may change over time to point to different values
197
+ 38 | };
198
+ 39 | // error: ref is a stable type but reactive
199
+ 40 | }, []);
200
+
201
+Inferred dependencies: `[ref]`
202
+```
203
+
204
+
\ No newline at end of file