Skip to content

Commit 0fcc286

Browse files
committed
refactor: improve React Hooks related utils
1 parent 14699c5 commit 0fcc286

File tree

15 files changed

+160
-181
lines changed

15 files changed

+160
-181
lines changed

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
## v0.10.1-beta.0 (Draft)
2+
3+
### Release Notes
4+
5+
#### 🏠 Internal
6+
7+
- `@eslint-react/core`
8+
- Improve React Hooks related utils.
9+
10+
#### Authors: 1
11+
12+
- Eva1ent ([@Rel1cx](https://github.com/Rel1cx))
13+
14+
---
15+
116
## v0.10.0 (Thu Dec 21 2023)
217

318
### Release Notes

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ module.exports = {
114114

115115
### JSX rules
116116

117-
- [ ] `jsx/max-depth`
117+
- [x] `jsx/max-depth`
118118

119119
### Naming convention rules
120120

packages/core/docs/README.md

Lines changed: 34 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,13 @@
6666
- [isForwardRefCall](README.md#isforwardrefcall)
6767
- [isFunctionOfRenderMethod](README.md#isfunctionofrendermethod)
6868
- [isInsideReactHook](README.md#isinsidereacthook)
69+
- [isInsideReactHookCall](README.md#isinsidereacthookcall)
6970
- [isInsideRenderMethod](README.md#isinsiderendermethod)
7071
- [isMemo](README.md#ismemo)
7172
- [isMemoCall](README.md#ismemocall)
7273
- [isPureComponent](README.md#ispurecomponent)
73-
- [isReactAPI](README.md#isreactapi)
74-
- [isReactAPICall](README.md#isreactapicall)
74+
- [isReactAPICallWithName](README.md#isreactapicallwithname)
75+
- [isReactAPIWithName](README.md#isreactapiwithname)
7576
- [isReactHook](README.md#isreacthook)
7677
- [isReactHookCall](README.md#isreacthookcall)
7778
- [isReactHookCallWithName](README.md#isreacthookcallwithname)
@@ -95,8 +96,6 @@
9596
- [isValidReactHookName](README.md#isvalidreacthookname)
9697
- [unsafeIsDeclaredInRenderProp](README.md#unsafeisdeclaredinrenderprop)
9798
- [unsafeIsDirectValueOfRenderProperty](README.md#unsafeisdirectvalueofrenderproperty)
98-
- [unsafeIsInsideReactHookCall](README.md#unsafeisinsidereacthookcall)
99-
- [unsafeIsReactHookCall](README.md#unsafeisreacthookcall)
10099
- [unsafeIsRenderFunction](README.md#unsafeisrenderfunction)
101100
- [unsafeIsRenderProp](README.md#unsafeisrenderprop)
102101

@@ -871,6 +870,22 @@ ___
871870

872871
___
873872

873+
### isInsideReactHookCall
874+
875+
**isInsideReactHookCall**(`node`): `boolean`
876+
877+
#### Parameters
878+
879+
| Name | Type |
880+
| :------ | :------ |
881+
| `node` | `Node` |
882+
883+
#### Returns
884+
885+
`boolean`
886+
887+
___
888+
874889
### isInsideRenderMethod
875890

876891
**isInsideRenderMethod**(`node`, `context`): `boolean`
@@ -959,9 +974,9 @@ Check if a node is a React PureComponent
959974

960975
___
961976

962-
### isReactAPI
977+
### isReactAPICallWithName
963978

964-
**isReactAPI**(`name`): `ReturnType`\<typeof `isFromPragma`\>
979+
**isReactAPICallWithName**(`name`): `ReturnType`\<typeof `isCallFromPragma`\>
965980

966981
#### Parameters
967982

@@ -971,9 +986,9 @@ ___
971986

972987
#### Returns
973988

974-
`ReturnType`\<typeof `isFromPragma`\>
989+
`ReturnType`\<typeof `isCallFromPragma`\>
975990

976-
**isReactAPI**(`name`, `member`): `ReturnType`\<typeof `isFromPragmaMember`\>
991+
**isReactAPICallWithName**(`name`, `member`): `ReturnType`\<typeof `isCallFromPragmaMember`\>
977992

978993
#### Parameters
979994

@@ -984,13 +999,13 @@ ___
984999

9851000
#### Returns
9861001

987-
`ReturnType`\<typeof `isFromPragmaMember`\>
1002+
`ReturnType`\<typeof `isCallFromPragmaMember`\>
9881003

9891004
___
9901005

991-
### isReactAPICall
1006+
### isReactAPIWithName
9921007

993-
**isReactAPICall**(`name`): `ReturnType`\<typeof `isCallFromPragma`\>
1008+
**isReactAPIWithName**(`name`): `ReturnType`\<typeof `isFromPragma`\>
9941009

9951010
#### Parameters
9961011

@@ -1000,9 +1015,9 @@ ___
10001015

10011016
#### Returns
10021017

1003-
`ReturnType`\<typeof `isCallFromPragma`\>
1018+
`ReturnType`\<typeof `isFromPragma`\>
10041019

1005-
**isReactAPICall**(`name`, `member`): `ReturnType`\<typeof `isCallFromPragmaMember`\>
1020+
**isReactAPIWithName**(`name`, `member`): `ReturnType`\<typeof `isFromPragmaMember`\>
10061021

10071022
#### Parameters
10081023

@@ -1013,7 +1028,7 @@ ___
10131028

10141029
#### Returns
10151030

1016-
`ReturnType`\<typeof `isCallFromPragmaMember`\>
1031+
`ReturnType`\<typeof `isFromPragmaMember`\>
10171032

10181033
___
10191034

@@ -1035,10 +1050,9 @@ ___
10351050

10361051
### isReactHookCall
10371052

1038-
**isReactHookCall**(`node`): `void`
1053+
**isReactHookCall**(`node`): `boolean`
10391054

1040-
TODO: Implement this function.
1041-
Check if the given node is a React Hook call by its name and its hierarchy.
1055+
Check if the given node is a React Hook call by its name.
10421056

10431057
#### Parameters
10441058

@@ -1048,7 +1062,9 @@ Check if the given node is a React Hook call by its name and its hierarchy.
10481062

10491063
#### Returns
10501064

1051-
`void`
1065+
`boolean`
1066+
1067+
`true` if the node is a React Hook call, `false` otherwise.
10521068

10531069
___
10541070

@@ -1455,42 +1471,6 @@ _ = <Component rows={ [{ render: () => <div /> }] } />
14551471

14561472
___
14571473

1458-
### unsafeIsInsideReactHookCall
1459-
1460-
**unsafeIsInsideReactHookCall**(`node`): `boolean`
1461-
1462-
#### Parameters
1463-
1464-
| Name | Type |
1465-
| :------ | :------ |
1466-
| `node` | `Node` |
1467-
1468-
#### Returns
1469-
1470-
`boolean`
1471-
1472-
___
1473-
1474-
### unsafeIsReactHookCall
1475-
1476-
**unsafeIsReactHookCall**(`node`): `boolean`
1477-
1478-
Check if the given node is a React Hook call by its name.
1479-
1480-
#### Parameters
1481-
1482-
| Name | Type | Description |
1483-
| :------ | :------ | :------ |
1484-
| `node` | `CallExpression` | The node to check. |
1485-
1486-
#### Returns
1487-
1488-
`boolean`
1489-
1490-
`true` if the node is a React hook call, `false` otherwise.
1491-
1492-
___
1493-
14941474
### unsafeIsRenderFunction
14951475

14961476
**unsafeIsRenderFunction**(`node`, `context`): `boolean`

packages/core/src/component/component-collector.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import type { ESLintUtils } from "@typescript-eslint/utils";
1717
import ShortUniqueId from "short-unique-id";
1818
import { match } from "ts-pattern";
1919

20-
import { unsafeIsReactHookCall } from "../hook";
20+
import { isReactHookCall } from "../hook";
2121
import type { ERFunctionComponent } from "./component";
2222
import { DEFAULT_COMPONENT_COLLECTOR_HINT, ERComponentCollectorHint } from "./component-collector-hint";
2323
import { ERFunctionComponentFlag } from "./component-flag";
@@ -192,7 +192,7 @@ export function componentCollector(
192192
});
193193
},
194194
"CallExpression:exit"(node: TSESTree.CallExpression) {
195-
if (!unsafeIsReactHookCall(node)) {
195+
if (!isReactHookCall(node)) {
196196
return;
197197
}
198198

packages/core/src/hook/hierarchy.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
import { isFunction, traverseUpGuard } from "@eslint-react/ast";
1+
import { is, isFunction, NodeType, traverseUp, traverseUpGuard } from "@eslint-react/ast";
22
import { O } from "@eslint-react/tools";
33
import type { TSESTree } from "@typescript-eslint/types";
44

5-
import { isReactHook } from "./is";
5+
import { isReactHook, isReactHookCall } from "./is";
66

77
export function isInsideReactHook(node: TSESTree.Node) {
88
return O.exists(traverseUpGuard(node, isFunction), isReactHook);
99
}
10+
11+
export function isInsideReactHookCall(node: TSESTree.Node): boolean {
12+
return O.isSome(traverseUp(node, n => is(NodeType.CallExpression)(n) && isReactHookCall(n)));
13+
}

packages/core/src/hook/hook-call.ts

Lines changed: 0 additions & 81 deletions
This file was deleted.

packages/core/src/hook/hook-collector.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import type { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
44
import ShortUniqueId from "short-unique-id";
55

66
import type { ERHook } from "./hook";
7-
import { unsafeIsReactHookCall } from "./hook-call";
87
import { isValidReactHookName } from "./hook-name";
8+
import { isReactHookCall } from "./is";
99

1010
const uid = new ShortUniqueId({ length: 10 });
1111

@@ -69,7 +69,7 @@ export function hookCollector(): {
6969
// In the realm of React, hooks are like colored functions, and defining a custom hook that doesn't call other hooks is like defining a generator function that doesn't yield or an async function that doesn't await.
7070
// "Custom Hooks may call other Hooks (that’s their whole purpose)." from https://react.dev/warnings/invalid-hook-call-warning
7171
// Further Reading: https://react.dev/learn/reusing-logic-with-custom-hooks#should-all-functions-called-during-rendering-start-with-the-use-prefix
72-
if (unsafeIsReactHookCall(node)) {
72+
if (isReactHookCall(node)) {
7373
const hook = Array
7474
.from(hooks.values())
7575
.find((hook) => hook.node === currentFn);

packages/core/src/hook/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
export * from "./hierarchy";
22
export * from "./hook";
3-
export * from "./hook-call";
43
export * from "./hook-collector";
54
export * from "./hook-name";
65
export * from "./is";

0 commit comments

Comments
 (0)