From eb3ad79d159d118ec32d8b2ae04cd70d1e483619 Mon Sep 17 00:00:00 2001 From: Nazar Koval Date: Fri, 20 Feb 2026 04:14:26 +0200 Subject: [PATCH 1/4] ref: apply React Compiler output to Component --- ...-passing-refs-in-object-as-props.expect.md | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-passing-refs-in-object-as-props.expect.md diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-passing-refs-in-object-as-props.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-passing-refs-in-object-as-props.expect.md new file mode 100644 index 00000000000..bf3d9ffbcc8 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-passing-refs-in-object-as-props.expect.md @@ -0,0 +1,51 @@ +## Input + +```javascript +function Component() { + const groupRefs = { + group1: useRef(null), + group2: useRef(null), + }; + return ( + <> + + + + ); +} + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; +function Component() { + const $ = _c(2); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = { group1: useRef(null), group2: useRef(null) }; + $[0] = t0; + } else { + t0 = $[0]; + } + const groupRefs = t0; + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + t1 = ( + <> + + + + ); + $[1] = t1; + } else { + t1 = $[1]; + } + return t1; +} + +``` + +### Eval output +(kind: exception) Fixture not implemented \ No newline at end of file From 29d24d847264a4717b2ea96c4e9263131518c6ca Mon Sep 17 00:00:00 2001 From: Nazar Koval Date: Fri, 20 Feb 2026 04:15:10 +0200 Subject: [PATCH 2/4] ref: extract refs into grouped object --- .../allow-passing-refs-in-object-as-props.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-passing-refs-in-object-as-props.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-passing-refs-in-object-as-props.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-passing-refs-in-object-as-props.js new file mode 100644 index 00000000000..04c301d0b68 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-passing-refs-in-object-as-props.js @@ -0,0 +1,12 @@ +function Component() { + const groupRefs = { + group1: useRef(null), + group2: useRef(null), + }; + return ( + <> + + + + ); +} \ No newline at end of file From ffa7e95210b87a7d6fc0705f71eb121fac95f5d2 Mon Sep 17 00:00:00 2001 From: Nazar Koval Date: Fri, 20 Feb 2026 04:16:09 +0200 Subject: [PATCH 3/4] fix: add dis comments --- ...use-ref-added-to-dep-without-type-info.expect.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-use-ref-added-to-dep-without-type-info.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-use-ref-added-to-dep-without-type-info.expect.md index 53bf66b1ee5..f37f0d284b4 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-use-ref-added-to-dep-without-type-info.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-use-ref-added-to-dep-without-type-info.expect.md @@ -41,13 +41,12 @@ Error: Cannot access refs during render React refs are values that are not needed for rendering. Refs should only be accessed outside of render, such as in event handlers or effects. Accessing a ref value (the `current` property) during render can cause your component not to update as expected (https://react.dev/reference/react/useRef). -error.invalid-use-ref-added-to-dep-without-type-info.ts:12:28 - 10 | const x = {a, val: val.ref.current}; +error.invalid-use-ref-added-to-dep-without-type-info.ts:10:21 + 8 | // however, this is an instance of accessing a ref during render and is disallowed + 9 | // under React's rules, so we reject this input +> 10 | const x = {a, val: val.ref.current}; + | ^^^^^^^^^^^^^^^ Cannot access ref value during render 11 | -> 12 | return ; - | ^ Cannot access ref value during render + 12 | return ; 13 | } - 14 | ``` - - \ No newline at end of file From d58aae13d41fef16392f80332bf975597e5ebb47 Mon Sep 17 00:00:00 2001 From: Nazar Koval Date: Fri, 20 Feb 2026 04:16:43 +0200 Subject: [PATCH 4/4] ref: removed useless usecase and remove type check --- .../src/Validation/ValidateNoRefAccessInRender.ts | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoRefAccessInRender.ts b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoRefAccessInRender.ts index dd7b04a11d6..d17a62e3119 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoRefAccessInRender.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoRefAccessInRender.ts @@ -151,16 +151,6 @@ function collectTemporariesSidemap(fn: HIRFunction, env: Env): void { break; } case 'PropertyLoad': { - if ( - isUseRefType(value.object.identifier) && - value.property === 'current' - ) { - continue; - } - const temp = env.lookup(value.object); - if (temp != null) { - env.define(lvalue, temp); - } break; } } @@ -375,7 +365,7 @@ function validateNoRefAccessInRenderImpl( const objType = env.get(instr.value.object.identifier.id); let lookupType: null | RefAccessType = null; if (objType?.kind === 'Structure') { - lookupType = objType.value; + lookupType = objType.value ?? objType; } else if (objType?.kind === 'Ref') { lookupType = { kind: 'RefValue',