dillon1000/react
Commit
Browse files PreserveMemo for useCallback transitively freezes function exprs
Merges `@enableTransitivelyFreezeFunctionExpressions` into the new
`@enablePreserveExistingMemoizationGuarantees` mode, since they are both
motivated by the same use case of preserving effect behavior by preserving
existing memoization behavior.
The idea is that `useCallback` has an implicit assumption: that the variables
captured by the callback aren't subsequently modified. Previous PRs treated the
values directly captured by the callback as frozen. But if those variables were
themselves another function expression, and that expression captured a mutable
value, then we wouldn't consider the freeze to be transitive:
```javascript
const object = makeObject();
useHook(); // oops, hook call inside `object`'s mutable range, can't memoize
object, log, or onClick!
const log = () => { console.log(object) };
const onClick = useCallback(() => { log() });
maybeMutate(object);
```
However, the assumption of such code is that it _doesn't_ modify such
transitively captured values. So here we merge
`@enableTransitivelyFreezeFunctionExpressions` mode into the
memoization-preserving mode. Now, the memoize instructions emitted for
useCallback (and useMemo) will transitively freeze captured function
expressions, allowing us to memoize.
The flip side of this is that some code may be violating these rules. We'll rely
on runtime validation to detect such cases.Changed paths7 files
First-parent comparisoncompiler/packages/babel-plugin-react-forget/src/HIR/Environment.ts ModifiedM compiler/packages/babel-plugin-react-forget/src/Inference/InferReferenceEffects.ts ModifiedM compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/transitive-freeze-array.expect.md ModifiedM compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/transitive-freeze-array.js ModifiedM compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/transitive-freeze-function-expressions.expect.md ModifiedM compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/transitive-freeze-function-expressions.js ModifiedM compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-call-second-function-which-captures-maybe-mutable-value-preserve-memoization.expect.md ModifiedPatch
Files changed
Rendering syntax-highlighted changes…