More test cases for useCallback
Adds test cases per the previous PR for useCallback: * callback that references another callback, which in turn references a possibly-mutated value * callback that references a ref
Joe Savona committed
Dec 15, 2023 at 15:19 UTC
08e92a3a8d3646138002322ab86b5d6fba9c162e
9 files changed
+410
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-call-second-function-which-captures-maybe-mutable-value-dont-preserve-memoization.expect.md
new
+84
@@ -0,0 +1,84 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+// @enablePreserveExistingMemoizationGuarantees:false
6
+import { useCallback } from "react";
7
+import {
8
+ identity,
9
+ logValue,
10
+ makeObject_Primitives,
11
+ useHook,
12
+} from "shared-runtime";
13
+
14
+function Component(props) {
15
+ const object = makeObject_Primitives();
16
+
17
+ useHook();
18
+
19
+ const log = () => {
20
+ logValue(object);
21
+ };
22
+
23
+ const onClick = useCallback(() => {
24
+ log();
25
+ }, [log]);
26
+
27
+ identity(object);
28
+
29
+ return <div onClick={onClick} />;
30
+}
31
+
32
+export const FIXTURE_ENTRYPOINT = {
33
+ fn: Component,
34
+ params: [{}],
35
+};
36
+
37
+```
38
+
39
+## Code
40
+
41
+```javascript
42
+// @enablePreserveExistingMemoizationGuarantees:false
43
+import { useCallback, unstable_useMemoCache as useMemoCache } from "react";
44
+import {
45
+ identity,
46
+ logValue,
47
+ makeObject_Primitives,
48
+ useHook,
49
+} from "shared-runtime";
50
+
51
+function Component(props) {
52
+ const $ = useMemoCache(1);
53
+ const object = makeObject_Primitives();
54
+
55
+ useHook();
56
+
57
+ const log = () => {
58
+ logValue(object);
59
+ };
60
+
61
+ const onClick = () => {
62
+ log();
63
+ };
64
+
65
+ identity(object);
66
+ let t0;
67
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
68
+ t0 = <div onClick={onClick} />;
69
+ $[0] = t0;
70
+ } else {
71
+ t0 = $[0];
72
+ }
73
+ return t0;
74
+}
75
+
76
+export const FIXTURE_ENTRYPOINT = {
77
+ fn: Component,
78
+ params: [{}],
79
+};
80
+
81
+```
82
+
83
+### Eval output
84
+(kind: ok) <div></div>
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-call-second-function-which-captures-maybe-mutable-value-dont-preserve-memoization.js
new
+31
@@ -0,0 +1,31 @@
1
+// @enablePreserveExistingMemoizationGuarantees:false
2
+import { useCallback } from "react";
3
+import {
4
+ identity,
5
+ logValue,
6
+ makeObject_Primitives,
7
+ useHook,
8
+} from "shared-runtime";
9
+
10
+function Component(props) {
11
+ const object = makeObject_Primitives();
12
+
13
+ useHook();
14
+
15
+ const log = () => {
16
+ logValue(object);
17
+ };
18
+
19
+ const onClick = useCallback(() => {
20
+ log();
21
+ }, [log]);
22
+
23
+ identity(object);
24
+
25
+ return <div onClick={onClick} />;
26
+}
27
+
28
+export const FIXTURE_ENTRYPOINT = {
29
+ fn: Component,
30
+ params: [{}],
31
+};
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-call-second-function-which-captures-maybe-mutable-value-preserve-memoization.expect.md
new
+84
@@ -0,0 +1,84 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+// @enablePreserveExistingMemoizationGuarantees
6
+import { useCallback } from "react";
7
+import {
8
+ identity,
9
+ logValue,
10
+ makeObject_Primitives,
11
+ useHook,
12
+} from "shared-runtime";
13
+
14
+function Component(props) {
15
+ const object = makeObject_Primitives();
16
+
17
+ useHook();
18
+
19
+ const log = () => {
20
+ logValue(object);
21
+ };
22
+
23
+ const onClick = useCallback(() => {
24
+ log();
25
+ }, [log]);
26
+
27
+ identity(object);
28
+
29
+ return <div onClick={onClick} />;
30
+}
31
+
32
+export const FIXTURE_ENTRYPOINT = {
33
+ fn: Component,
34
+ params: [{}],
35
+};
36
+
37
+```
38
+
39
+## Code
40
+
41
+```javascript
42
+// @enablePreserveExistingMemoizationGuarantees
43
+import { useCallback, unstable_useMemoCache as useMemoCache } from "react";
44
+import {
45
+ identity,
46
+ logValue,
47
+ makeObject_Primitives,
48
+ useHook,
49
+} from "shared-runtime";
50
+
51
+function Component(props) {
52
+ const $ = useMemoCache(1);
53
+ const object = makeObject_Primitives();
54
+
55
+ useHook();
56
+
57
+ const log = () => {
58
+ logValue(object);
59
+ };
60
+
61
+ const onClick = () => {
62
+ log();
63
+ };
64
+
65
+ identity(object);
66
+ let t0;
67
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
68
+ t0 = <div onClick={onClick} />;
69
+ $[0] = t0;
70
+ } else {
71
+ t0 = $[0];
72
+ }
73
+ return t0;
74
+}
75
+
76
+export const FIXTURE_ENTRYPOINT = {
77
+ fn: Component,
78
+ params: [{}],
79
+};
80
+
81
+```
82
+
83
+### Eval output
84
+(kind: ok) <div></div>
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-call-second-function-which-captures-maybe-mutable-value-preserve-memoization.js
new
+31
@@ -0,0 +1,31 @@
1
+// @enablePreserveExistingMemoizationGuarantees
2
+import { useCallback } from "react";
3
+import {
4
+ identity,
5
+ logValue,
6
+ makeObject_Primitives,
7
+ useHook,
8
+} from "shared-runtime";
9
+
10
+function Component(props) {
11
+ const object = makeObject_Primitives();
12
+
13
+ useHook();
14
+
15
+ const log = () => {
16
+ logValue(object);
17
+ };
18
+
19
+ const onClick = useCallback(() => {
20
+ log();
21
+ }, [log]);
22
+
23
+ identity(object);
24
+
25
+ return <div onClick={onClick} />;
26
+}
27
+
28
+export const FIXTURE_ENTRYPOINT = {
29
+ fn: Component,
30
+ params: [{}],
31
+};
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-value-dont-preserve-memoization.expect.md
new
+69
@@ -0,0 +1,69 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+// @enablePreserveExistingMemoizationGuarantees
6
+import { useCallback, useRef } from "react";
7
+
8
+function Component(props) {
9
+ const ref = useRef(null);
10
+
11
+ const onChange = useCallback((event) => {
12
+ // The ref should still be mutable here even though function deps are frozen in
13
+ // @enablePreserveExistingMemoizationGuarantees mode
14
+ ref.current = event.target.value;
15
+ });
16
+
17
+ return <input onChange={onChange} />;
18
+}
19
+
20
+export const FIXTURE_ENTRYPOINT = {
21
+ fn: Component,
22
+ params: [{}],
23
+};
24
+
25
+```
26
+
27
+## Code
28
+
29
+```javascript
30
+// @enablePreserveExistingMemoizationGuarantees
31
+import {
32
+ useCallback,
33
+ useRef,
34
+ unstable_useMemoCache as useMemoCache,
35
+} from "react";
36
+
37
+function Component(props) {
38
+ const $ = useMemoCache(3);
39
+ const ref = useRef(null);
40
+ let t0;
41
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
42
+ t0 = (event) => {
43
+ ref.current = event.target.value;
44
+ };
45
+ $[0] = t0;
46
+ } else {
47
+ t0 = $[0];
48
+ }
49
+ const onChange = t0;
50
+ let t1;
51
+ if ($[1] !== onChange) {
52
+ t1 = <input onChange={onChange} />;
53
+ $[1] = onChange;
54
+ $[2] = t1;
55
+ } else {
56
+ t1 = $[2];
57
+ }
58
+ return t1;
59
+}
60
+
61
+export const FIXTURE_ENTRYPOINT = {
62
+ fn: Component,
63
+ params: [{}],
64
+};
65
+
66
+```
67
+
68
+### Eval output
69
+(kind: ok) <input>
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-value-dont-preserve-memoization.js
new
+19
@@ -0,0 +1,19 @@
1
+// @enablePreserveExistingMemoizationGuarantees
2
+import { useCallback, useRef } from "react";
3
+
4
+function Component(props) {
5
+ const ref = useRef(null);
6
+
7
+ const onChange = useCallback((event) => {
8
+ // The ref should still be mutable here even though function deps are frozen in
9
+ // @enablePreserveExistingMemoizationGuarantees mode
10
+ ref.current = event.target.value;
11
+ });
12
+
13
+ return <input onChange={onChange} />;
14
+}
15
+
16
+export const FIXTURE_ENTRYPOINT = {
17
+ fn: Component,
18
+ params: [{}],
19
+};
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-value-preserve-memoization.expect.md
new
+69
@@ -0,0 +1,69 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+// @enablePreserveExistingMemoizationGuarantees
6
+import { useCallback, useRef } from "react";
7
+
8
+function Component(props) {
9
+ const ref = useRef(null);
10
+
11
+ const onChange = useCallback((event) => {
12
+ // The ref should still be mutable here even though function deps are frozen in
13
+ // @enablePreserveExistingMemoizationGuarantees mode
14
+ ref.current = event.target.value;
15
+ });
16
+
17
+ return <input onChange={onChange} />;
18
+}
19
+
20
+export const FIXTURE_ENTRYPOINT = {
21
+ fn: Component,
22
+ params: [{}],
23
+};
24
+
25
+```
26
+
27
+## Code
28
+
29
+```javascript
30
+// @enablePreserveExistingMemoizationGuarantees
31
+import {
32
+ useCallback,
33
+ useRef,
34
+ unstable_useMemoCache as useMemoCache,
35
+} from "react";
36
+
37
+function Component(props) {
38
+ const $ = useMemoCache(3);
39
+ const ref = useRef(null);
40
+ let t0;
41
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
42
+ t0 = (event) => {
43
+ ref.current = event.target.value;
44
+ };
45
+ $[0] = t0;
46
+ } else {
47
+ t0 = $[0];
48
+ }
49
+ const onChange = t0;
50
+ let t1;
51
+ if ($[1] !== onChange) {
52
+ t1 = <input onChange={onChange} />;
53
+ $[1] = onChange;
54
+ $[2] = t1;
55
+ } else {
56
+ t1 = $[2];
57
+ }
58
+ return t1;
59
+}
60
+
61
+export const FIXTURE_ENTRYPOINT = {
62
+ fn: Component,
63
+ params: [{}],
64
+};
65
+
66
+```
67
+
68
+### Eval output
69
+(kind: ok) <input>
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-value-preserve-memoization.js
new
+19
@@ -0,0 +1,19 @@
1
+// @enablePreserveExistingMemoizationGuarantees
2
+import { useCallback, useRef } from "react";
3
+
4
+function Component(props) {
5
+ const ref = useRef(null);
6
+
7
+ const onChange = useCallback((event) => {
8
+ // The ref should still be mutable here even though function deps are frozen in
9
+ // @enablePreserveExistingMemoizationGuarantees mode
10
+ ref.current = event.target.value;
11
+ });
12
+
13
+ return <input onChange={onChange} />;
14
+}
15
+
16
+export const FIXTURE_ENTRYPOINT = {
17
+ fn: Component,
18
+ params: [{}],
19
+};
compiler/packages/sprout/src/shared-runtime.ts
+4
@@ -153,6 +153,10 @@ export function throwInput(x: Object): never {
153
throw x;
154
}
155
156
+export function logValue<T>(value: T): void {
157
+ console.log(value);
158
+}
159
+
160
export function useHook(): Object {
161
return makeObject_Primitives();
162
}