Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -402,14 +402,26 @@ function validateNoRefAccessInRenderImpl(
}
const objType = env.get(instr.value.object.identifier.id);
let lookupType: null | RefAccessType = null;
if (objType?.kind === 'Structure') {
lookupType = objType.value;
} else if (objType?.kind === 'Ref') {
lookupType = {
kind: 'RefValue',
loc: instr.loc,
refId: objType.refId,
};
if (objType?.kind === 'Ref') {
// Only loading .current from a ref should be treated as a ref value access
if (
instr.value.kind === 'PropertyLoad' &&
instr.value.property === 'current'
) {
lookupType = {
kind: 'RefValue',
loc: instr.loc,
refId: objType.refId,
};
}
} else if (objType?.kind === 'Structure') {
// For structures (like props objects or objects containing refs),
// we should not automatically propagate the ref type to all properties.
// Only propagate if we're destructuring the entire object or if the
// specific property is known to be a ref.
// This prevents false positives where props.className is flagged as a ref
// just because props also contains props.ref.
lookupType = null;
}
env.set(
instr.lvalue.identifier.id,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// @compilationMode(infer)
// Regression test for https://github.com/facebook/react/issues/34775
// The compiler should NOT flag props.className as a ref access just because
// props also contains props.ref. Each property should be independently typed.

import {useCallback} from 'react';

function Child(props: {className: string, myRef: () => void}) {
const internalRef = useCallback(() => {
console.log('ref');
}, []);

return (
<div>
<div ref={internalRef} className={props.className} />
<div ref={props.myRef} className={props.className} />
</div>
);
}

export function Parent() {
const ref = useCallback(() => {
console.log('ref');
}, []);

return <Child myRef={ref} className="foo" />;
}

export const FIXTURE_ENTRYPOINT = {
fn: Parent,
params: [],
};