-
Notifications
You must be signed in to change notification settings - Fork 47.3k
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]: React Compiler should error on document.getElementById call during render #31932
Comments
Thanks for posting! Reading external mutable values during render is against the rules in React: components should render the same result given the same props, state, and context. getElementById() accesses external mutable state - the DOM - which can change w/o React being aware. Read more here: https://react.dev/reference/rules#components-and-hooks-must-be-pure Instead, React supports features like refs to get a reference to a DOM node, or useEffect to run side effects (where it is safe to access external mutable state). I would recommend moving the access of the element into a useEffect call, and storing that current value in a ref (from useRef()). The compiler tries to detect invalid code like in the example and skip compilation, but we can’t detect all possible patterns. In this case we could consider looking for getElementById() calls and bailing out (w an InvalidReact error). Cc @poteto |
Thank you so much for the detailed explanation, @josephsavona! You're absolutely right - this is a pure function violation and I should have known better. I somehow missed that getElementById is accessing external mutable state here. What made me report this was actually the silent failure - I was expecting the compiler to either bail out or show an error. I completely understand that detecting all possible patterns across all platforms (web, native) isn't feasible. I'm curious though - would detecting web-specific APIs like common DOM queries (getElementById, querySelector) create too tight of a coupling, or would there be a way to conditionally run this kind of validation based on platform? Probably having the ESLint plugin warn about such usages could be enough? I'm currently working on adopting the React compiler in the content form of Hygraph CMS, and while it's been working great overall (except for a few React Hook Form issues I've already solved), this particular case silently broke our form functionality. Having the compiler, or the ESLint plugin warn about these common pitfalls would be super helpful for the adoption journey. |
I've started the validation in #31960 |
What kind of issue is this?
Link to repro
https://playground.react.dev/#N4Igzg9grgTgxgUxALhAMygOzgFwJYSYAEAIngIYA2EA5gOp44AWAChDDlQBTBF5gB5AA4JiAXwCURYAB1iROITA4FhTnkwIYRALxEcATxEQ0RACYQ4UALaiVAQh16ZILGYRoNCMy6IB+c0sbOwA6GgQcAFFKBFtMHAAhAwBJMy4AciF2TkoAWhgICBx0qWQiTChKSgBuOSIiGAjYYi46+qIAHjIqWiIIEUwdYH5hUTEAPjb2zu7qGhC2DipVePIvGCHFVfWJqemZijmQgGE1O3GACQQqiA6AelnaE7P4yflp+8f5xZy3j4fDrQ-kQJLVMGIQGIgA
Repro steps
Steps to reproduce
Expected behavior:
Actual behaviour:
The issue is in how the compiler transforms the code:
How often does this bug happen?
Every time
What version of React are you using?
^18.2.0
What version of React Compiler are you using?
19.0.0-beta-201e55d-20241215
The text was updated successfully, but these errors were encountered: