facebook/react

[compiler] "Rendered fewer hooks than expected" error when using a function that starts with an uppercase character

gimenete opened this issue · 3 comments

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/#N4Igzg9grgTgxgUxALhASwLYAcIwC4AEwBUYCAyngIZ4IEC+BAZjBBgQOQwJVx4cAdAHaYc+AgCUefACIB5ALLNW7LtLwBaACZsA9HAA2aBEP7DhcCELCEpWVgQC8BABQBKJwD4iwggUvWhADaAPoANARkeJQ0CAC6TiRkMbQueDBQCG6+BNx4sEKuOX4APJ7FfgQlAEZQeHhWBFYAwkZwANaOwO5ekQjR1KnVvQCE1W70ngpU7XQYdHAwVGAAFiW6tfVW5YWVpViewM0raAZazWw4QiZ47vTrBxXrO37ZQvTmQgE2BMen55crDdEj1HN5gDk8gUqp5AImE-ja7QIeBWdE2DSEz2EHyEwikvDw8gUADpFjxaBIIBBbjo4FB5qZiQBzfoAUQMCAZeAAQgBPACSWhcXCp-DcbmJ3CEWgQMBcJTsDl0njeIHoQA

Repro steps

The application crashes when clicking the button. The the local state of Repro changes so it re-rendereds and that's when the error is triggered.

  • If the ChildComponent function is renamed to childComponent, the issue disappears.
  • If the ChildComponent function is refactored to an arrow function with implicit return, the issue disappears: const ChildComponent = () => <>↑ click the button</>
  • When rendering the child component as usual (<ChildComponent /> the error is not triggered). I know that should be the normal thing to do, but I had this problem because a third party library was expecting children components being of a specific types. I started doing regular components and when I noticed that limitation I changed them to function calls and that's when I found this problem in the react compiler.

This issue doesn't happen when the application is built without the babel-plugin-react-compiler plugin.

react-compiler-repro-bttn.mp4

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-0dec889-20241115

Thanks for posting! However this doesn’t reproduce the issue as we understood it. Note that the compilation is the same regardless of whether the function name is lowercase or uppercase. It is unsafe to call components as functions - if that call gets memoized (by the compiler or manually by someone who doesn’t realize it’s a component) it will lead to the error here.

The fix is to use JSX to invoke the component. Can you clarify a bit more why that doesn’t work?

because a third party library was expecting children components being of a specific types

which library? Are there docs you can point to? This sounds like a problematic pattern.

which library? Are there docs you can point to? This sounds like a problematic pattern.

This is the component: TreeView from GitHub's design system. However I upgraded recently to their latest version and it feels like that's no longer an issue. I've changed my code to use normal JSX syntax and it works now without issues.