@samitouri / QOS-React-2 / commits / f9f084087f

Fixture for reactively-controlled context variables

Mofei considered this case, it works thanks to the handling for function expressions earlier in the stack.

Joe Savona committed Jan 23, 2024 at 08:59 UTC f9f084087f7eb8a6b56a89db850cb4dddef0ac66
2 files changed +145
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/reactive-control-dependency-on-context-variable.expect.md new
+108
@@ -0,0 +1,108 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +import { identity } from "shared-runtime";
6 +
7 +function Component(props) {
8 + let x;
9 + // Reassign `x` based on a reactive value, but inside a function expression
10 + // to make it a context variable
11 + const f = () => {
12 + if (props.cond) {
13 + x = 1;
14 + } else {
15 + x = 2;
16 + }
17 + };
18 + // Pass `f` through a function to prevent IIFE inlining optimizations
19 + const f2 = identity(f);
20 + f2();
21 +
22 + // The values assigned to `x` are non-reactive, but the value of `x`
23 + // depends on the "control" value `props.cond` which is reactive.
24 + // Therefore x should be treated as reactive too.
25 + return [x];
26 +}
27 +
28 +export const FIXTURE_ENTRYPOINT = {
29 + fn: Component,
30 + params: [],
31 + sequentialRenders: [
32 + { cond: true },
33 + { cond: true },
34 + { cond: false },
35 + { cond: false },
36 + { cond: true },
37 + { cond: false },
38 + { cond: true },
39 + { cond: false },
40 + ],
41 +};
42 +
43 +```
44 +
45 +## Code
46 +
47 +```javascript
48 +import { unstable_useMemoCache as useMemoCache } from "react";
49 +import { identity } from "shared-runtime";
50 +
51 +function Component(props) {
52 + const $ = useMemoCache(4);
53 + let x;
54 + if ($[0] !== props.cond) {
55 + const f = () => {
56 + if (props.cond) {
57 + x = 1;
58 + } else {
59 + x = 2;
60 + }
61 + };
62 +
63 + const f2 = identity(f);
64 + f2();
65 + $[0] = props.cond;
66 + $[1] = x;
67 + } else {
68 + x = $[1];
69 + }
70 +
71 + const t0 = x;
72 + let t1;
73 + if ($[2] !== t0) {
74 + t1 = [t0];
75 + $[2] = t0;
76 + $[3] = t1;
77 + } else {
78 + t1 = $[3];
79 + }
80 + return t1;
81 +}
82 +
83 +export const FIXTURE_ENTRYPOINT = {
84 + fn: Component,
85 + params: [],
86 + sequentialRenders: [
87 + { cond: true },
88 + { cond: true },
89 + { cond: false },
90 + { cond: false },
91 + { cond: true },
92 + { cond: false },
93 + { cond: true },
94 + { cond: false },
95 + ],
96 +};
97 +
98 +```
99 +
100 +### Eval output
101 +(kind: ok) [1]
102 +[1]
103 +[2]
104 +[2]
105 +[1]
106 +[2]
107 +[1]
108 +[2]
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/reactive-control-dependency-on-context-variable.js new
+37
@@ -0,0 +1,37 @@
1 +import { identity } from "shared-runtime";
2 +
3 +function Component(props) {
4 + let x;
5 + // Reassign `x` based on a reactive value, but inside a function expression
6 + // to make it a context variable
7 + const f = () => {
8 + if (props.cond) {
9 + x = 1;
10 + } else {
11 + x = 2;
12 + }
13 + };
14 + // Pass `f` through a function to prevent IIFE inlining optimizations
15 + const f2 = identity(f);
16 + f2();
17 +
18 + // The values assigned to `x` are non-reactive, but the value of `x`
19 + // depends on the "control" value `props.cond` which is reactive.
20 + // Therefore x should be treated as reactive too.
21 + return [x];
22 +}
23 +
24 +export const FIXTURE_ENTRYPOINT = {
25 + fn: Component,
26 + params: [],
27 + sequentialRenders: [
28 + { cond: true },
29 + { cond: true },
30 + { cond: false },
31 + { cond: false },
32 + { cond: true },
33 + { cond: false },
34 + { cond: true },
35 + { cond: false },
36 + ],
37 +};