eslint-plugin-react-hooks-extra 1.23.2-next.3 → 1.23.2

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.
Files changed (3) hide show
  1. package/dist/index.js +99 -87
  2. package/dist/index.mjs +99 -87
  3. package/package.json +13 -13
package/dist/index.js CHANGED
@@ -31,7 +31,7 @@ var VAR5__namespace = /*#__PURE__*/_interopNamespace(VAR5);
31
31
 
32
32
  // package.json
33
33
  var name = "eslint-plugin-react-hooks-extra";
34
- var version = "1.23.2-next.3";
34
+ var version = "1.23.2";
35
35
  var createRule = shared.createRuleForPlugin("hooks-extra");
36
36
  function isFromHookCall(name2, context, settings, predicate = eff.F.constTrue) {
37
37
  const hookAlias = settings.additionalHooks?.[name2] ?? [];
@@ -161,46 +161,53 @@ var no_direct_set_state_in_use_effect_default = createRule({
161
161
  }
162
162
  return {
163
163
  ":function"(node) {
164
- const functionKind = getFunctionKind(node);
165
- functionStack.push([node, functionKind]);
166
- if (functionKind === "setup") onSetupFunctionEnter(node);
164
+ const kind = getFunctionKind(node);
165
+ functionStack.push({ kind, node });
166
+ if (kind === "setup") {
167
+ onSetupFunctionEnter(node);
168
+ }
167
169
  },
168
170
  ":function:exit"(node) {
169
- const [_, functionKind] = functionStack.at(-1) ?? [];
171
+ const { kind } = functionStack.at(-1) ?? {};
172
+ if (kind === "setup") {
173
+ onSetupFunctionExit(node);
174
+ }
170
175
  functionStack.pop();
171
- if (functionKind === "setup") onSetupFunctionExit(node);
172
176
  },
173
177
  CallExpression(node) {
174
- const effectFn = eff.O.getOrNull(setupFunctionRef.current);
175
- const [parentFn, parentFnKind] = functionStack.at(-1) ?? [];
176
- if (parentFn?.async) return;
178
+ const setupFunction = eff.O.getOrNull(setupFunctionRef.current);
179
+ const pEntry = functionStack.at(-1);
180
+ if (pEntry?.node.async) return;
177
181
  tsPattern.match(getCallKind(node)).with("setState", () => {
178
- if (!parentFn) return;
179
- if (parentFn !== effectFn && parentFnKind !== "immediate") {
180
- const maybeVd = AST2__namespace.traverseUpGuard(node, isVariableDeclaratorFromHookCall);
181
- if (eff.O.isSome(maybeVd)) {
182
- const vd = maybeVd.value;
183
- const calls2 = indSetStateCallsInUseMemoOrCallback.get(vd.init) ?? [];
184
- indSetStateCallsInUseMemoOrCallback.set(vd.init, [...calls2, node]);
182
+ if (!pEntry) return;
183
+ switch (true) {
184
+ case (pEntry.node === setupFunction || pEntry.kind === "immediate"): {
185
+ context.report({
186
+ messageId: "noDirectSetStateInUseEffect",
187
+ node,
188
+ data: {
189
+ name: context.sourceCode.getText(node.callee)
190
+ }
191
+ });
185
192
  return;
186
193
  }
187
- const calls = indSetStateCalls.get(parentFn) ?? [];
188
- indSetStateCalls.set(parentFn, [...calls, node]);
189
- return;
194
+ default: {
195
+ const mbVariableDeclarator = AST2__namespace.findParentNodeGuard(node, isVariableDeclaratorFromHookCall);
196
+ if (eff.O.isNone(mbVariableDeclarator)) {
197
+ const calls = indSetStateCalls.get(pEntry.node) ?? [];
198
+ indSetStateCalls.set(pEntry.node, [...calls, node]);
199
+ return;
200
+ }
201
+ const vd = mbVariableDeclarator.value;
202
+ const prevs = indSetStateCallsInUseMemoOrCallback.get(vd.init) ?? [];
203
+ indSetStateCallsInUseMemoOrCallback.set(vd.init, [...prevs, node]);
204
+ }
190
205
  }
191
- context.report({
192
- messageId: "noDirectSetStateInUseEffect",
193
- node,
194
- data: { name: context.sourceCode.getText(node.callee) }
195
- });
196
206
  }).with("useEffect", () => {
197
- const [firstArg] = node.arguments;
198
- if (AST2__namespace.isFunction(firstArg)) return;
199
- const identifiers = AST2__namespace.getNestedIdentifiers(node);
200
- setupFunctionIdentifiers.push(...identifiers);
207
+ if (AST2__namespace.isFunction(node.arguments.at(0))) return;
208
+ setupFunctionIdentifiers.push(...AST2__namespace.getNestedIdentifiers(node));
201
209
  }).with("other", () => {
202
- const isInSetupFunction = effectFn === parentFn;
203
- if (!isInSetupFunction) return;
210
+ if (pEntry?.node !== setupFunction) return;
204
211
  indFunctionCalls.push(node);
205
212
  }).otherwise(eff.F.constVoid);
206
213
  },
@@ -212,26 +219,25 @@ var no_direct_set_state_in_use_effect_default = createRule({
212
219
  const parent = node.parent.parent;
213
220
  if (parent.type !== types.AST_NODE_TYPES.CallExpression) break;
214
221
  if (!isUseMemoCall2(parent)) break;
215
- const maybeVd = AST2__namespace.traverseUpGuard(parent, isVariableDeclaratorFromHookCall);
216
- if (eff.O.isNone(maybeVd)) break;
217
- const vd = maybeVd.value;
218
- const calls = indSetStateCallsInUseEffectArg0.get(vd.init) ?? [];
219
- indSetStateCallsInUseEffectArg0.set(vd.init, [...calls, node]);
222
+ const mbVariableDeclarator = AST2__namespace.findParentNodeGuard(parent, isVariableDeclaratorFromHookCall);
223
+ if (eff.O.isNone(mbVariableDeclarator)) break;
224
+ const variableDeclarator = mbVariableDeclarator.value;
225
+ const calls = indSetStateCallsInUseEffectArg0.get(variableDeclarator.init) ?? [];
226
+ indSetStateCallsInUseEffectArg0.set(variableDeclarator.init, [...calls, node]);
220
227
  break;
221
228
  }
222
229
  case types.AST_NODE_TYPES.CallExpression: {
223
- const [firstArg] = node.parent.arguments;
224
- if (node !== firstArg) break;
230
+ if (node !== node.parent.arguments.at(0)) break;
225
231
  if (isUseCallbackCall2(node.parent)) {
226
- const maybeVd = AST2__namespace.traverseUpGuard(node.parent, isVariableDeclaratorFromHookCall);
227
- if (eff.O.isNone(maybeVd)) break;
228
- const vd = maybeVd.value;
229
- const calls = indSetStateCallsInUseEffectArg0.get(vd.init) ?? [];
230
- indSetStateCallsInUseEffectArg0.set(vd.init, [...calls, node]);
232
+ const mbVariableDeclarator = AST2__namespace.findParentNodeGuard(node.parent, isVariableDeclaratorFromHookCall);
233
+ if (eff.O.isNone(mbVariableDeclarator)) break;
234
+ const variableDeclarator = mbVariableDeclarator.value;
235
+ const prevs = indSetStateCallsInUseEffectArg0.get(variableDeclarator.init) ?? [];
236
+ indSetStateCallsInUseEffectArg0.set(variableDeclarator.init, [...prevs, node]);
231
237
  }
232
238
  if (isUseEffectLikeCall(node.parent)) {
233
- const calls = indSetStateCallsInUseEffectArg0.get(node.parent) ?? [];
234
- indSetStateCallsInUseEffectSetup.set(node.parent, [...calls, node]);
239
+ const prevs = indSetStateCallsInUseEffectArg0.get(node.parent) ?? [];
240
+ indSetStateCallsInUseEffectSetup.set(node.parent, [...prevs, node]);
235
241
  }
236
242
  break;
237
243
  }
@@ -346,46 +352,53 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
346
352
  }
347
353
  return {
348
354
  ":function"(node) {
349
- const functionKind = getFunctionKind(node);
350
- functionStack.push([node, functionKind]);
351
- if (functionKind === "setup") onSetupFunctionEnter(node);
355
+ const kind = getFunctionKind(node);
356
+ functionStack.push({ kind, node });
357
+ if (kind === "setup") {
358
+ onSetupFunctionEnter(node);
359
+ }
352
360
  },
353
361
  ":function:exit"(node) {
354
- const [_, functionKind] = functionStack.at(-1) ?? [];
362
+ const { kind } = functionStack.at(-1) ?? {};
363
+ if (kind === "setup") {
364
+ onSetupFunctionExit(node);
365
+ }
355
366
  functionStack.pop();
356
- if (functionKind === "setup") onSetupFunctionExit(node);
357
367
  },
358
368
  CallExpression(node) {
359
- const effectFn = eff.O.getOrNull(setupFunctionRef.current);
360
- const [parentFn, parentFnKind] = functionStack.at(-1) ?? [];
361
- if (parentFn?.async) return;
369
+ const setupFunction = eff.O.getOrNull(setupFunctionRef.current);
370
+ const pEntry = functionStack.at(-1);
371
+ if (pEntry?.node.async) return;
362
372
  tsPattern.match(getCallKind(node)).with("setState", () => {
363
- if (!parentFn) return;
364
- if (parentFn !== effectFn && parentFnKind !== "immediate") {
365
- const maybeVd = AST2__namespace.traverseUpGuard(node, isVariableDeclaratorFromHookCall);
366
- if (eff.O.isSome(maybeVd)) {
367
- const vd = maybeVd.value;
368
- const calls2 = indSetStateCallsInUseMemoOrCallback.get(vd.init) ?? [];
369
- indSetStateCallsInUseMemoOrCallback.set(vd.init, [...calls2, node]);
373
+ if (!pEntry) return;
374
+ switch (true) {
375
+ case (pEntry.node === setupFunction || pEntry.kind === "immediate"): {
376
+ context.report({
377
+ messageId: "noDirectSetStateInUseLayoutEffect",
378
+ node,
379
+ data: {
380
+ name: context.sourceCode.getText(node.callee)
381
+ }
382
+ });
370
383
  return;
371
384
  }
372
- const calls = indSetStateCalls.get(parentFn) ?? [];
373
- indSetStateCalls.set(parentFn, [...calls, node]);
374
- return;
385
+ default: {
386
+ const mbVariableDeclarator = AST2__namespace.findParentNodeGuard(node, isVariableDeclaratorFromHookCall);
387
+ if (eff.O.isNone(mbVariableDeclarator)) {
388
+ const calls = indSetStateCalls.get(pEntry.node) ?? [];
389
+ indSetStateCalls.set(pEntry.node, [...calls, node]);
390
+ return;
391
+ }
392
+ const vd = mbVariableDeclarator.value;
393
+ const prevs = indSetStateCallsInUseMemoOrCallback.get(vd.init) ?? [];
394
+ indSetStateCallsInUseMemoOrCallback.set(vd.init, [...prevs, node]);
395
+ }
375
396
  }
376
- context.report({
377
- messageId: "noDirectSetStateInUseLayoutEffect",
378
- node,
379
- data: { name: context.sourceCode.getText(node.callee) }
380
- });
381
397
  }).with("useLayoutEffect", () => {
382
- const [firstArg] = node.arguments;
383
- if (AST2__namespace.isFunction(firstArg)) return;
384
- const identifiers = AST2__namespace.getNestedIdentifiers(node);
385
- setupFunctionIdentifiers.push(...identifiers);
398
+ if (AST2__namespace.isFunction(node.arguments.at(0))) return;
399
+ setupFunctionIdentifiers.push(...AST2__namespace.getNestedIdentifiers(node));
386
400
  }).with("other", () => {
387
- const isInSetupFunction = effectFn === parentFn;
388
- if (!isInSetupFunction) return;
401
+ if (pEntry?.node !== setupFunction) return;
389
402
  indFunctionCalls.push(node);
390
403
  }).otherwise(eff.F.constVoid);
391
404
  },
@@ -397,26 +410,25 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
397
410
  const parent = node.parent.parent;
398
411
  if (parent.type !== types.AST_NODE_TYPES.CallExpression) break;
399
412
  if (!isUseMemoCall2(parent)) break;
400
- const maybeVd = AST2__namespace.traverseUpGuard(parent, isVariableDeclaratorFromHookCall);
401
- if (eff.O.isNone(maybeVd)) break;
402
- const vd = maybeVd.value;
403
- const calls = indSetStateCallsInUseLayoutEffectArg0.get(vd.init) ?? [];
404
- indSetStateCallsInUseLayoutEffectArg0.set(vd.init, [...calls, node]);
413
+ const mbVariableDeclarator = AST2__namespace.findParentNodeGuard(parent, isVariableDeclaratorFromHookCall);
414
+ if (eff.O.isNone(mbVariableDeclarator)) break;
415
+ const variableDeclarator = mbVariableDeclarator.value;
416
+ const calls = indSetStateCallsInUseLayoutEffectArg0.get(variableDeclarator.init) ?? [];
417
+ indSetStateCallsInUseLayoutEffectArg0.set(variableDeclarator.init, [...calls, node]);
405
418
  break;
406
419
  }
407
420
  case types.AST_NODE_TYPES.CallExpression: {
408
- const [firstArg] = node.parent.arguments;
409
- if (node !== firstArg) break;
421
+ if (node !== node.parent.arguments.at(0)) break;
410
422
  if (isUseCallbackCall2(node.parent)) {
411
- const maybeVd = AST2__namespace.traverseUpGuard(node.parent, isVariableDeclaratorFromHookCall);
412
- if (eff.O.isNone(maybeVd)) break;
413
- const vd = maybeVd.value;
414
- const calls = indSetStateCallsInUseLayoutEffectArg0.get(vd.init) ?? [];
415
- indSetStateCallsInUseLayoutEffectArg0.set(vd.init, [...calls, node]);
423
+ const mbVariableDeclarator = AST2__namespace.findParentNodeGuard(node.parent, isVariableDeclaratorFromHookCall);
424
+ if (eff.O.isNone(mbVariableDeclarator)) break;
425
+ const variableDeclarator = mbVariableDeclarator.value;
426
+ const prevs = indSetStateCallsInUseLayoutEffectArg0.get(variableDeclarator.init) ?? [];
427
+ indSetStateCallsInUseLayoutEffectArg0.set(variableDeclarator.init, [...prevs, node]);
416
428
  }
417
429
  if (isUseLayoutEffectLikeCall(node.parent)) {
418
- const calls = indSetStateCallsInUseLayoutEffectArg0.get(node.parent) ?? [];
419
- indSetStateCallsInUseLayoutEffectSetup.set(node.parent, [...calls, node]);
430
+ const prevs = indSetStateCallsInUseLayoutEffectArg0.get(node.parent) ?? [];
431
+ indSetStateCallsInUseLayoutEffectSetup.set(node.parent, [...prevs, node]);
420
432
  }
421
433
  break;
422
434
  }
package/dist/index.mjs CHANGED
@@ -8,7 +8,7 @@ import { match, isMatching } from 'ts-pattern';
8
8
 
9
9
  // package.json
10
10
  var name = "eslint-plugin-react-hooks-extra";
11
- var version = "1.23.2-next.3";
11
+ var version = "1.23.2";
12
12
  var createRule = createRuleForPlugin("hooks-extra");
13
13
  function isFromHookCall(name2, context, settings, predicate = F.constTrue) {
14
14
  const hookAlias = settings.additionalHooks?.[name2] ?? [];
@@ -138,46 +138,53 @@ var no_direct_set_state_in_use_effect_default = createRule({
138
138
  }
139
139
  return {
140
140
  ":function"(node) {
141
- const functionKind = getFunctionKind(node);
142
- functionStack.push([node, functionKind]);
143
- if (functionKind === "setup") onSetupFunctionEnter(node);
141
+ const kind = getFunctionKind(node);
142
+ functionStack.push({ kind, node });
143
+ if (kind === "setup") {
144
+ onSetupFunctionEnter(node);
145
+ }
144
146
  },
145
147
  ":function:exit"(node) {
146
- const [_, functionKind] = functionStack.at(-1) ?? [];
148
+ const { kind } = functionStack.at(-1) ?? {};
149
+ if (kind === "setup") {
150
+ onSetupFunctionExit(node);
151
+ }
147
152
  functionStack.pop();
148
- if (functionKind === "setup") onSetupFunctionExit(node);
149
153
  },
150
154
  CallExpression(node) {
151
- const effectFn = O.getOrNull(setupFunctionRef.current);
152
- const [parentFn, parentFnKind] = functionStack.at(-1) ?? [];
153
- if (parentFn?.async) return;
155
+ const setupFunction = O.getOrNull(setupFunctionRef.current);
156
+ const pEntry = functionStack.at(-1);
157
+ if (pEntry?.node.async) return;
154
158
  match(getCallKind(node)).with("setState", () => {
155
- if (!parentFn) return;
156
- if (parentFn !== effectFn && parentFnKind !== "immediate") {
157
- const maybeVd = AST2.traverseUpGuard(node, isVariableDeclaratorFromHookCall);
158
- if (O.isSome(maybeVd)) {
159
- const vd = maybeVd.value;
160
- const calls2 = indSetStateCallsInUseMemoOrCallback.get(vd.init) ?? [];
161
- indSetStateCallsInUseMemoOrCallback.set(vd.init, [...calls2, node]);
159
+ if (!pEntry) return;
160
+ switch (true) {
161
+ case (pEntry.node === setupFunction || pEntry.kind === "immediate"): {
162
+ context.report({
163
+ messageId: "noDirectSetStateInUseEffect",
164
+ node,
165
+ data: {
166
+ name: context.sourceCode.getText(node.callee)
167
+ }
168
+ });
162
169
  return;
163
170
  }
164
- const calls = indSetStateCalls.get(parentFn) ?? [];
165
- indSetStateCalls.set(parentFn, [...calls, node]);
166
- return;
171
+ default: {
172
+ const mbVariableDeclarator = AST2.findParentNodeGuard(node, isVariableDeclaratorFromHookCall);
173
+ if (O.isNone(mbVariableDeclarator)) {
174
+ const calls = indSetStateCalls.get(pEntry.node) ?? [];
175
+ indSetStateCalls.set(pEntry.node, [...calls, node]);
176
+ return;
177
+ }
178
+ const vd = mbVariableDeclarator.value;
179
+ const prevs = indSetStateCallsInUseMemoOrCallback.get(vd.init) ?? [];
180
+ indSetStateCallsInUseMemoOrCallback.set(vd.init, [...prevs, node]);
181
+ }
167
182
  }
168
- context.report({
169
- messageId: "noDirectSetStateInUseEffect",
170
- node,
171
- data: { name: context.sourceCode.getText(node.callee) }
172
- });
173
183
  }).with("useEffect", () => {
174
- const [firstArg] = node.arguments;
175
- if (AST2.isFunction(firstArg)) return;
176
- const identifiers = AST2.getNestedIdentifiers(node);
177
- setupFunctionIdentifiers.push(...identifiers);
184
+ if (AST2.isFunction(node.arguments.at(0))) return;
185
+ setupFunctionIdentifiers.push(...AST2.getNestedIdentifiers(node));
178
186
  }).with("other", () => {
179
- const isInSetupFunction = effectFn === parentFn;
180
- if (!isInSetupFunction) return;
187
+ if (pEntry?.node !== setupFunction) return;
181
188
  indFunctionCalls.push(node);
182
189
  }).otherwise(F.constVoid);
183
190
  },
@@ -189,26 +196,25 @@ var no_direct_set_state_in_use_effect_default = createRule({
189
196
  const parent = node.parent.parent;
190
197
  if (parent.type !== AST_NODE_TYPES.CallExpression) break;
191
198
  if (!isUseMemoCall2(parent)) break;
192
- const maybeVd = AST2.traverseUpGuard(parent, isVariableDeclaratorFromHookCall);
193
- if (O.isNone(maybeVd)) break;
194
- const vd = maybeVd.value;
195
- const calls = indSetStateCallsInUseEffectArg0.get(vd.init) ?? [];
196
- indSetStateCallsInUseEffectArg0.set(vd.init, [...calls, node]);
199
+ const mbVariableDeclarator = AST2.findParentNodeGuard(parent, isVariableDeclaratorFromHookCall);
200
+ if (O.isNone(mbVariableDeclarator)) break;
201
+ const variableDeclarator = mbVariableDeclarator.value;
202
+ const calls = indSetStateCallsInUseEffectArg0.get(variableDeclarator.init) ?? [];
203
+ indSetStateCallsInUseEffectArg0.set(variableDeclarator.init, [...calls, node]);
197
204
  break;
198
205
  }
199
206
  case AST_NODE_TYPES.CallExpression: {
200
- const [firstArg] = node.parent.arguments;
201
- if (node !== firstArg) break;
207
+ if (node !== node.parent.arguments.at(0)) break;
202
208
  if (isUseCallbackCall2(node.parent)) {
203
- const maybeVd = AST2.traverseUpGuard(node.parent, isVariableDeclaratorFromHookCall);
204
- if (O.isNone(maybeVd)) break;
205
- const vd = maybeVd.value;
206
- const calls = indSetStateCallsInUseEffectArg0.get(vd.init) ?? [];
207
- indSetStateCallsInUseEffectArg0.set(vd.init, [...calls, node]);
209
+ const mbVariableDeclarator = AST2.findParentNodeGuard(node.parent, isVariableDeclaratorFromHookCall);
210
+ if (O.isNone(mbVariableDeclarator)) break;
211
+ const variableDeclarator = mbVariableDeclarator.value;
212
+ const prevs = indSetStateCallsInUseEffectArg0.get(variableDeclarator.init) ?? [];
213
+ indSetStateCallsInUseEffectArg0.set(variableDeclarator.init, [...prevs, node]);
208
214
  }
209
215
  if (isUseEffectLikeCall(node.parent)) {
210
- const calls = indSetStateCallsInUseEffectArg0.get(node.parent) ?? [];
211
- indSetStateCallsInUseEffectSetup.set(node.parent, [...calls, node]);
216
+ const prevs = indSetStateCallsInUseEffectArg0.get(node.parent) ?? [];
217
+ indSetStateCallsInUseEffectSetup.set(node.parent, [...prevs, node]);
212
218
  }
213
219
  break;
214
220
  }
@@ -323,46 +329,53 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
323
329
  }
324
330
  return {
325
331
  ":function"(node) {
326
- const functionKind = getFunctionKind(node);
327
- functionStack.push([node, functionKind]);
328
- if (functionKind === "setup") onSetupFunctionEnter(node);
332
+ const kind = getFunctionKind(node);
333
+ functionStack.push({ kind, node });
334
+ if (kind === "setup") {
335
+ onSetupFunctionEnter(node);
336
+ }
329
337
  },
330
338
  ":function:exit"(node) {
331
- const [_, functionKind] = functionStack.at(-1) ?? [];
339
+ const { kind } = functionStack.at(-1) ?? {};
340
+ if (kind === "setup") {
341
+ onSetupFunctionExit(node);
342
+ }
332
343
  functionStack.pop();
333
- if (functionKind === "setup") onSetupFunctionExit(node);
334
344
  },
335
345
  CallExpression(node) {
336
- const effectFn = O.getOrNull(setupFunctionRef.current);
337
- const [parentFn, parentFnKind] = functionStack.at(-1) ?? [];
338
- if (parentFn?.async) return;
346
+ const setupFunction = O.getOrNull(setupFunctionRef.current);
347
+ const pEntry = functionStack.at(-1);
348
+ if (pEntry?.node.async) return;
339
349
  match(getCallKind(node)).with("setState", () => {
340
- if (!parentFn) return;
341
- if (parentFn !== effectFn && parentFnKind !== "immediate") {
342
- const maybeVd = AST2.traverseUpGuard(node, isVariableDeclaratorFromHookCall);
343
- if (O.isSome(maybeVd)) {
344
- const vd = maybeVd.value;
345
- const calls2 = indSetStateCallsInUseMemoOrCallback.get(vd.init) ?? [];
346
- indSetStateCallsInUseMemoOrCallback.set(vd.init, [...calls2, node]);
350
+ if (!pEntry) return;
351
+ switch (true) {
352
+ case (pEntry.node === setupFunction || pEntry.kind === "immediate"): {
353
+ context.report({
354
+ messageId: "noDirectSetStateInUseLayoutEffect",
355
+ node,
356
+ data: {
357
+ name: context.sourceCode.getText(node.callee)
358
+ }
359
+ });
347
360
  return;
348
361
  }
349
- const calls = indSetStateCalls.get(parentFn) ?? [];
350
- indSetStateCalls.set(parentFn, [...calls, node]);
351
- return;
362
+ default: {
363
+ const mbVariableDeclarator = AST2.findParentNodeGuard(node, isVariableDeclaratorFromHookCall);
364
+ if (O.isNone(mbVariableDeclarator)) {
365
+ const calls = indSetStateCalls.get(pEntry.node) ?? [];
366
+ indSetStateCalls.set(pEntry.node, [...calls, node]);
367
+ return;
368
+ }
369
+ const vd = mbVariableDeclarator.value;
370
+ const prevs = indSetStateCallsInUseMemoOrCallback.get(vd.init) ?? [];
371
+ indSetStateCallsInUseMemoOrCallback.set(vd.init, [...prevs, node]);
372
+ }
352
373
  }
353
- context.report({
354
- messageId: "noDirectSetStateInUseLayoutEffect",
355
- node,
356
- data: { name: context.sourceCode.getText(node.callee) }
357
- });
358
374
  }).with("useLayoutEffect", () => {
359
- const [firstArg] = node.arguments;
360
- if (AST2.isFunction(firstArg)) return;
361
- const identifiers = AST2.getNestedIdentifiers(node);
362
- setupFunctionIdentifiers.push(...identifiers);
375
+ if (AST2.isFunction(node.arguments.at(0))) return;
376
+ setupFunctionIdentifiers.push(...AST2.getNestedIdentifiers(node));
363
377
  }).with("other", () => {
364
- const isInSetupFunction = effectFn === parentFn;
365
- if (!isInSetupFunction) return;
378
+ if (pEntry?.node !== setupFunction) return;
366
379
  indFunctionCalls.push(node);
367
380
  }).otherwise(F.constVoid);
368
381
  },
@@ -374,26 +387,25 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
374
387
  const parent = node.parent.parent;
375
388
  if (parent.type !== AST_NODE_TYPES.CallExpression) break;
376
389
  if (!isUseMemoCall2(parent)) break;
377
- const maybeVd = AST2.traverseUpGuard(parent, isVariableDeclaratorFromHookCall);
378
- if (O.isNone(maybeVd)) break;
379
- const vd = maybeVd.value;
380
- const calls = indSetStateCallsInUseLayoutEffectArg0.get(vd.init) ?? [];
381
- indSetStateCallsInUseLayoutEffectArg0.set(vd.init, [...calls, node]);
390
+ const mbVariableDeclarator = AST2.findParentNodeGuard(parent, isVariableDeclaratorFromHookCall);
391
+ if (O.isNone(mbVariableDeclarator)) break;
392
+ const variableDeclarator = mbVariableDeclarator.value;
393
+ const calls = indSetStateCallsInUseLayoutEffectArg0.get(variableDeclarator.init) ?? [];
394
+ indSetStateCallsInUseLayoutEffectArg0.set(variableDeclarator.init, [...calls, node]);
382
395
  break;
383
396
  }
384
397
  case AST_NODE_TYPES.CallExpression: {
385
- const [firstArg] = node.parent.arguments;
386
- if (node !== firstArg) break;
398
+ if (node !== node.parent.arguments.at(0)) break;
387
399
  if (isUseCallbackCall2(node.parent)) {
388
- const maybeVd = AST2.traverseUpGuard(node.parent, isVariableDeclaratorFromHookCall);
389
- if (O.isNone(maybeVd)) break;
390
- const vd = maybeVd.value;
391
- const calls = indSetStateCallsInUseLayoutEffectArg0.get(vd.init) ?? [];
392
- indSetStateCallsInUseLayoutEffectArg0.set(vd.init, [...calls, node]);
400
+ const mbVariableDeclarator = AST2.findParentNodeGuard(node.parent, isVariableDeclaratorFromHookCall);
401
+ if (O.isNone(mbVariableDeclarator)) break;
402
+ const variableDeclarator = mbVariableDeclarator.value;
403
+ const prevs = indSetStateCallsInUseLayoutEffectArg0.get(variableDeclarator.init) ?? [];
404
+ indSetStateCallsInUseLayoutEffectArg0.set(variableDeclarator.init, [...prevs, node]);
393
405
  }
394
406
  if (isUseLayoutEffectLikeCall(node.parent)) {
395
- const calls = indSetStateCallsInUseLayoutEffectArg0.get(node.parent) ?? [];
396
- indSetStateCallsInUseLayoutEffectSetup.set(node.parent, [...calls, node]);
407
+ const prevs = indSetStateCallsInUseLayoutEffectArg0.get(node.parent) ?? [];
408
+ indSetStateCallsInUseLayoutEffectSetup.set(node.parent, [...prevs, node]);
397
409
  }
398
410
  break;
399
411
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-react-hooks-extra",
3
- "version": "1.23.2-next.3",
3
+ "version": "1.23.2",
4
4
  "description": "ESLint React's ESLint plugin for React Hooks related rules.",
5
5
  "keywords": [
6
6
  "react",
@@ -42,22 +42,22 @@
42
42
  "./package.json"
43
43
  ],
44
44
  "dependencies": {
45
- "@typescript-eslint/scope-manager": "^8.19.0",
46
- "@typescript-eslint/type-utils": "^8.19.0",
47
- "@typescript-eslint/types": "^8.19.0",
48
- "@typescript-eslint/utils": "^8.19.0",
45
+ "@typescript-eslint/scope-manager": "^8.19.1",
46
+ "@typescript-eslint/type-utils": "^8.19.1",
47
+ "@typescript-eslint/types": "^8.19.1",
48
+ "@typescript-eslint/utils": "^8.19.1",
49
49
  "string-ts": "^2.2.0",
50
50
  "ts-pattern": "^5.6.0",
51
- "@eslint-react/ast": "1.23.2-next.3",
52
- "@eslint-react/core": "1.23.2-next.3",
53
- "@eslint-react/eff": "1.23.2-next.3",
54
- "@eslint-react/shared": "1.23.2-next.3",
55
- "@eslint-react/types": "1.23.2-next.3",
56
- "@eslint-react/jsx": "1.23.2-next.3",
57
- "@eslint-react/var": "1.23.2-next.3"
51
+ "@eslint-react/ast": "1.23.2",
52
+ "@eslint-react/core": "1.23.2",
53
+ "@eslint-react/eff": "1.23.2",
54
+ "@eslint-react/jsx": "1.23.2",
55
+ "@eslint-react/shared": "1.23.2",
56
+ "@eslint-react/types": "1.23.2",
57
+ "@eslint-react/var": "1.23.2"
58
58
  },
59
59
  "devDependencies": {
60
- "@types/react": "^19.0.2",
60
+ "@types/react": "^19.0.3",
61
61
  "@types/react-dom": "^19.0.2",
62
62
  "tsup": "^8.3.5",
63
63
  "@workspace/configs": "0.0.0"