diff --git a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoDerivedComputationsInEffects.ts b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoDerivedComputationsInEffects.ts
index 4a99c2f945..061a5a273f 100644
--- a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoDerivedComputationsInEffects.ts
+++ b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoDerivedComputationsInEffects.ts
@@ -307,6 +307,19 @@ function validateEffect(
sourceIds: argMetadata.sourcesIds,
});
}
+ } else if (instr.value.kind === 'CallExpression') {
+ const calleeMetadata = derivationCache.get(
+ instr.value.callee.identifier.id,
+ );
+
+ if (
+ calleeMetadata !== undefined &&
+ (calleeMetadata.typeOfValue === 'fromProps' ||
+ calleeMetadata.typeOfValue === 'fromPropsAndState')
+ ) {
+ // If the callee is a prop we can't confidently say that it should be derived in render
+ return;
+ }
}
}
seenBlocks.add(block.id);
diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-prop-function-call-no-error.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-prop-function-call-no-error.expect.md
new file mode 100644
index 0000000000..afae2c20a6
--- /dev/null
+++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-prop-function-call-no-error.expect.md
@@ -0,0 +1,75 @@
+
+## Input
+
+```javascript
+// @validateNoDerivedComputationsInEffects
+import {useEffect, useState} from 'react';
+
+function Component({propValue, onChange}) {
+ const [value, setValue] = useState(null);
+ useEffect(() => {
+ setValue(propValue);
+ onChange();
+ }, [propValue]);
+
+ return
{value}
;
+}
+
+export const FIXTURE_ENTRYPOINT = {
+ fn: Component,
+ params: [{propValue: 'test', onChange: () => {}}],
+};
+
+```
+
+## Code
+
+```javascript
+import { c as _c } from "react/compiler-runtime"; // @validateNoDerivedComputationsInEffects
+import { useEffect, useState } from "react";
+
+function Component(t0) {
+ const $ = _c(7);
+ const { propValue, onChange } = t0;
+ const [value, setValue] = useState(null);
+ let t1;
+ if ($[0] !== onChange || $[1] !== propValue) {
+ t1 = () => {
+ setValue(propValue);
+ onChange();
+ };
+ $[0] = onChange;
+ $[1] = propValue;
+ $[2] = t1;
+ } else {
+ t1 = $[2];
+ }
+ let t2;
+ if ($[3] !== propValue) {
+ t2 = [propValue];
+ $[3] = propValue;
+ $[4] = t2;
+ } else {
+ t2 = $[4];
+ }
+ useEffect(t1, t2);
+ let t3;
+ if ($[5] !== value) {
+ t3 = {value}
;
+ $[5] = value;
+ $[6] = t3;
+ } else {
+ t3 = $[6];
+ }
+ return t3;
+}
+
+export const FIXTURE_ENTRYPOINT = {
+ fn: Component,
+ params: [{ propValue: "test", onChange: () => {} }],
+};
+
+```
+
+### Eval output
+(kind: ok) test
\ No newline at end of file
diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-prop-function-call-no-error.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-prop-function-call-no-error.js
new file mode 100644
index 0000000000..aba975e899
--- /dev/null
+++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/effect-derived-computations/effect-contains-prop-function-call-no-error.js
@@ -0,0 +1,17 @@
+// @validateNoDerivedComputationsInEffects
+import {useEffect, useState} from 'react';
+
+function Component({propValue, onChange}) {
+ const [value, setValue] = useState(null);
+ useEffect(() => {
+ setValue(propValue);
+ onChange();
+ }, [propValue]);
+
+ return {value}
;
+}
+
+export const FIXTURE_ENTRYPOINT = {
+ fn: Component,
+ params: [{propValue: 'test', onChange: () => {}}],
+};