Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Compiler Bug]: #31396

Open
1 of 4 tasks
stipsan opened this issue Nov 1, 2024 · 3 comments
Open
1 of 4 tasks

[Compiler Bug]: #31396

stipsan opened this issue Nov 1, 2024 · 3 comments
Labels
Component: Optimizing Compiler Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug Type: Bug

Comments

@stipsan
Copy link

stipsan commented Nov 1, 2024

What kind of issue is this?

  • React Compiler core (the JS output is incorrect, or your app works incorrectly after optimization)
  • babel-plugin-react-compiler (build issue installing or using the Babel plugin)
  • eslint-plugin-react-compiler (build issue installing or using the eslint plugin)
  • react-compiler-healthcheck (build issue installing or using the healthcheck script)

Link to repro

https://playground.react.dev/#N4Igzg9grgTgxgUxALhASwLYAcIwC4AEwBUYCAsghhADQlkBKCAZnaQgMICGANjwEZc4AawIBfAsxgQMBADogYCIXgUBuOQDtMOfEQJ4AFtLx4eCcZOmyFPCABMuYQ+q1aEAD12F7LLlB5CZihNODw0CE0CcgBPAEEsLAAKAEoiLQICOEiwQiVmAgBeegQmZlSNKIysnMIjEzMEewAxCDhSIpLKaiTqzNSigD4+zINjCFNzXqjR2YHCwYJ8gDp2mCVNPAB+ZeY20lSaEdmAVgAGM6OZ2czgY5vzLns0TQBzZEleMiubm7wYLhoHgvd4GGBQBA-X7iKGzFKwggAbT27TAAF0oSlKtV2ABRZjMBBhJLzRbAeoTRotfZgVJiOiIimTJqtVFolJuGZKPCwKIAHmeADclixCsB8mJBgAJBB8CAEADquB49j5AHohYNKmItCAxEA

Repro steps

The compiler assumes that ref.current is called during render when inside of useMemo(), even when useMemo is returning a callback that is only called in a useEffect and never during render. See playground for the code.

The most common use case for specifying a callback with useMemo instead of useCallback, is when the callback is wrapped in a debouncing technique, like lodash/throttle:

  const throttledFocus = useMemo(
    () =>
      throttle(
        () => ref.current?.focus(),
        500,
        {
          leading: false,
          trailing: true,
        },
      ),
    [focus],
  );

It's as if the compiler isn't differentiating the closure that returns the memoized value (and thus is indeed firing during render), and useMemo returning a callback 🤔

How often does this bug happen?

Every time

What version of React are you using?

^18.3.1

What version of React Compiler are you using?

19.0.0-beta-6fc168f-20241025

@stipsan stipsan added Component: Optimizing Compiler Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug Type: Bug labels Nov 1, 2024
@stipsan
Copy link
Author

stipsan commented Nov 1, 2024

More context: portabletext/editor#327 although we found a workaround in this particular case, moving the throttle creation into the useEffect itself. There are cases where we don't have a workaround to this.

@gsathya
Copy link
Contributor

gsathya commented Nov 1, 2024

cc @mvitousek

@josephsavona
Copy link
Contributor

Thanks for reporting. My guess is that it's the FinishMemoize instruction which tricks us into thinking the ref is accessed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Optimizing Compiler Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug Type: Bug
Projects
None yet
Development

No branches or pull requests

3 participants