Detect unknown hooks on React namespace
Handles an edge-case from earlier in the stack. When looking up a property on a shape, if the property is defined we return it. But if it isn't defined, and the property name is a hook, we treat it like a default custom hook.
Joe Savona committed
Oct 3, 2023 at 09:00 UTC
b7a14ecc8d931922b44e92496eedf9710ea3ce39
4 files changed
+48
-7
compiler/packages/babel-plugin-react-forget/src/HIR/Environment.ts
+6
-3
@@ -374,9 +374,12 @@ export class Environment {
374
loc: null,
375
suggestions: null,
376
});
377
- return (
378
- shape.properties.get(property) ?? shape.properties.get("*") ?? null
379
- );
377
+ let value =
378
+ shape.properties.get(property) ?? shape.properties.get("*") ?? null;
379
+ if (value === null && isHookName(property)) {
380
+ value = this.#getCustomHookType();
381
+ }
382
+ return value;
383
} else if (isHookName(property)) {
384
return this.#getCustomHookType();
385
} else {
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/drop-methodcall-usememo.expect.md
+13
-4
@@ -27,21 +27,30 @@ import { unstable_useMemoCache as useMemoCache } from "react";
27
import * as React from "react";
28
29
function Component(props) {
30
- const $ = useMemoCache(2);
30
+ const $ = useMemoCache(4);
31
const c_0 = $[0] !== props.value;
32
let t0;
33
if (c_0) {
34
- t0 = (() => {
34
+ t0 = () => {
35
const x = [];
36
x.push(props.value);
37
return x;
38
- })();
38
+ };
39
$[0] = props.value;
40
$[1] = t0;
41
} else {
42
t0 = $[1];
43
}
44
- const x_0 = t0;
44
+ const c_2 = $[2] !== t0;
45
+ let t1;
46
+ if (c_2) {
47
+ t1 = t0();
48
+ $[2] = t0;
49
+ $[3] = t1;
50
+ } else {
51
+ t1 = $[3];
52
+ }
53
+ const x_0 = t1;
54
return x_0;
55
}
56
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.conditional-hook-unknown-hook-react-namespace.expect.md
new
+22
@@ -0,0 +1,22 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+function Component(props) {
6
+ let x = null;
7
+ if (props.cond) {
8
+ x = React.useNonexistentHook();
9
+ }
10
+ return x;
11
+}
12
+
13
+```
14
+
15
+
16
+## Error
17
+
18
+```
19
+[ReactForget] InvalidReact: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) (4:4)
20
+```
21
+
22
+
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.conditional-hook-unknown-hook-react-namespace.js
new
+7
@@ -0,0 +1,7 @@
1
+function Component(props) {
2
+ let x = null;
3
+ if (props.cond) {
4
+ x = React.useNonexistentHook();
5
+ }
6
+ return x;
7
+}