@samitouri / QOS-React / commits / 0b32173d09
Fork 0

The library for web and native user interfaces.

More fixtures for useCallback with refs

Extra fixture confirming that some usage of refs can break memoization, both in normal mode and in preserve-existing-memo mode.

Joe Savona committed Dec 15, 2023 at 16:22 UTC 0b32173d0995ad581513ff5d226b010fd117395c
4 files changed +183
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-dont-preserve-memoization.expect.md new
+67
@@ -0,0 +1,67 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +// @enablePreserveExistingMemoizationGuarantees:false
6 +import { useCallback, useRef } from "react";
7 +
8 +function Component(props) {
9 + const ref = useRef({ inner: 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.inner = event.target.value;
15 + });
16 +
17 + ref.current.inner = null;
18 +
19 + return <input onChange={onChange} />;
20 +}
21 +
22 +export const FIXTURE_ENTRYPOINT = {
23 + fn: Component,
24 + params: [{}],
25 +};
26 +
27 +```
28 +
29 +## Code
30 +
31 +```javascript
32 +// @enablePreserveExistingMemoizationGuarantees:false
33 +import {
34 + useCallback,
35 + useRef,
36 + unstable_useMemoCache as useMemoCache,
37 +} from "react";
38 +
39 +function Component(props) {
40 + const $ = useMemoCache(2);
41 + const ref = useRef({ inner: null });
42 +
43 + const onChange = (event) => {
44 + ref.current.inner = event.target.value;
45 + };
46 +
47 + ref.current.inner = null;
48 + let t0;
49 + if ($[0] !== onChange) {
50 + t0 = <input onChange={onChange} />;
51 + $[0] = onChange;
52 + $[1] = t0;
53 + } else {
54 + t0 = $[1];
55 + }
56 + return t0;
57 +}
58 +
59 +export const FIXTURE_ENTRYPOINT = {
60 + fn: Component,
61 + params: [{}],
62 +};
63 +
64 +```
65 +
66 +### Eval output
67 +(kind: ok) <input>
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-dont-preserve-memoization.js new
+21
@@ -0,0 +1,21 @@
1 +// @enablePreserveExistingMemoizationGuarantees:false
2 +import { useCallback, useRef } from "react";
3 +
4 +function Component(props) {
5 + const ref = useRef({ inner: 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.inner = event.target.value;
11 + });
12 +
13 + ref.current.inner = null;
14 +
15 + return <input onChange={onChange} />;
16 +}
17 +
18 +export const FIXTURE_ENTRYPOINT = {
19 + fn: Component,
20 + params: [{}],
21 +};
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-preserve-memoization.expect.md new
+74
@@ -0,0 +1,74 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +// @enablePreserveExistingMemoizationGuarantees
6 +import { useCallback, useRef } from "react";
7 +
8 +function Component(props) {
9 + const ref = useRef({ inner: 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.inner = event.target.value;
15 + });
16 +
17 + ref.current.inner = null;
18 +
19 + return <input onChange={onChange} />;
20 +}
21 +
22 +export const FIXTURE_ENTRYPOINT = {
23 + fn: Component,
24 + params: [{}],
25 +};
26 +
27 +```
28 +
29 +## Code
30 +
31 +```javascript
32 +// @enablePreserveExistingMemoizationGuarantees
33 +import {
34 + useCallback,
35 + useRef,
36 + unstable_useMemoCache as useMemoCache,
37 +} from "react";
38 +
39 +function Component(props) {
40 + const $ = useMemoCache(3);
41 + let t0;
42 + if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
43 + t0 = { inner: null };
44 + $[0] = t0;
45 + } else {
46 + t0 = $[0];
47 + }
48 + const ref = useRef(t0);
49 +
50 + const onChange = (event) => {
51 + ref.current.inner = event.target.value;
52 + };
53 +
54 + ref.current.inner = null;
55 + let t1;
56 + if ($[1] !== onChange) {
57 + t1 = <input onChange={onChange} />;
58 + $[1] = onChange;
59 + $[2] = t1;
60 + } else {
61 + t1 = $[2];
62 + }
63 + return t1;
64 +}
65 +
66 +export const FIXTURE_ENTRYPOINT = {
67 + fn: Component,
68 + params: [{}],
69 +};
70 +
71 +```
72 +
73 +### Eval output
74 +(kind: ok) <input>
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-preserve-memoization.js new
+21
@@ -0,0 +1,21 @@
1 +// @enablePreserveExistingMemoizationGuarantees
2 +import { useCallback, useRef } from "react";
3 +
4 +function Component(props) {
5 + const ref = useRef({ inner: 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.inner = event.target.value;
11 + });
12 +
13 + ref.current.inner = null;
14 +
15 + return <input onChange={onChange} />;
16 +}
17 +
18 +export const FIXTURE_ENTRYPOINT = {
19 + fn: Component,
20 + params: [{}],
21 +};