-
Notifications
You must be signed in to change notification settings - Fork 46.9k
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
Bug: First render doesn't create DOM nodes before next javascript is executed in script #30886
Comments
Hi @bryceosterhaus! Try this, it should work: // REACT 18
const root = ReactDOM.createRoot(document.getElementById("app18"));
ReactDOM.flushSync(() =>
root.render(
React.createElement("div", { id: "child18" }, "THIS DOESN'T WORK")
)
);
document.getElementById("child17").innerHTML = "THIS WORKS!";
document.getElementById("child18").innerHTML = "THIS WORKS!"; |
You really shouldn't alter nodes created by React from the outside as it'll mismatch from the virtual dom. Any particular use case I'm missing? Besides, |
It isn't ideal, but in our use case it is possible that we would render part of the page with a shared React component and then a team or customer may want to write their own inline javascript that reads some data from the DOM that React created. The server then puts all these together on the same page. For example: // Rendered by the platform
<script type="text/javascript">
const root = //...
root.render(<Button id="myButton" />);
</script>
// Added by another team/customer
<script type="text/javascript">
const button = document.getElementById('myButton');
// do something here with button...
</script> Regardless, it still strikes me as odd that before/after React 18, this behavior is significantly different. |
Thanks @gianlucadifrancesco, that does work. I still find it an odd behavior though, especially because just reading through a script like my example above, it isn't intuitive that the element won't be created in time. I know React 18+ has async rendering now, but I didn't expect my script to continue executing without the DOM being created yet for that initial render. |
This may have been discussed elsewhere but I wasn't able to find anything.
With the update to using
createRoot
in React 18, the DOM is created asynchronously, which means any code running afterroot.render()
cannot depend on the DOM that React is creating.React version: 18.2.0
Steps To Reproduce
The current behavior
JS will error because
document.getElementById("reactChild")
is null and not foundThe expected behavior
React will render first and then
document.getElementById("reactChild")
will execute find the nodeLink to code example
Is this just an expected result with React 18+? If you fallback and use
ReactDOM.render()
instead, it works as expected.The text was updated successfully, but these errors were encountered: