diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/mutation-during-jsx-construction.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/mutation-during-jsx-construction.expect.md new file mode 100644 index 0000000000..5975d82411 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/mutation-during-jsx-construction.expect.md @@ -0,0 +1,53 @@ + +## Input + +```javascript +import { identity, mutate, mutateAndReturnNewValue } from "shared-runtime"; + +function Component(props) { + const key = {}; + // Key is modified by the function, but key itself is not frozen + const element =
{props.value}
; + // Key is later mutated here: this mutation must be grouped with the + // jsx construction above + mutate(key); + return element; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], +}; + +``` + +## Code + +```javascript +import { unstable_useMemoCache as useMemoCache } from "react"; +import { identity, mutate, mutateAndReturnNewValue } from "shared-runtime"; + +function Component(props) { + const $ = useMemoCache(2); + let element; + if ($[0] !== props.value) { + const key = {}; + + element =
{props.value}
; + + mutate(key); + $[0] = props.value; + $[1] = element; + } else { + element = $[1]; + } + return element; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], +}; + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/mutation-during-jsx-construction.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/mutation-during-jsx-construction.js new file mode 100644 index 0000000000..1d7302bce5 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/mutation-during-jsx-construction.js @@ -0,0 +1,16 @@ +import { identity, mutate, mutateAndReturnNewValue } from "shared-runtime"; + +function Component(props) { + const key = {}; + // Key is modified by the function, but key itself is not frozen + const element =
{props.value}
; + // Key is later mutated here: this mutation must be grouped with the + // jsx construction above + mutate(key); + return element; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], +}; diff --git a/compiler/packages/sprout/src/shared-runtime.ts b/compiler/packages/sprout/src/shared-runtime.ts index 928c064fee..880b5df848 100644 --- a/compiler/packages/sprout/src/shared-runtime.ts +++ b/compiler/packages/sprout/src/shared-runtime.ts @@ -73,6 +73,11 @@ export function mutateAndReturn(arg: T): T { return arg; } +export function mutateAndReturnNewValue(arg: T): string { + mutate(arg); + return "hello!"; +} + export function setProperty(arg: any, property: any): void { // don't mutate primitive if (typeof arg === null || typeof arg !== "object") {