I do ReactDOM.render #container element(top-level) in componentDidMount function, React show me some error, Cannot read property 'rootID' of null.
If I use setTimeout run ReactDOM.render, it's work. (Even after 0ms)
I feel uncertain, could someone help me?
html:
<!DOCTYPE html>
<html>
<head>
<title>React</title>
</head>
<body>
<div id="container"></div>
<script type="text/javascript" src="script/lib/react.js"></script>
<script type="text/javascript" src="script/lib/react-dom.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
<script type="text/javascript" src="script/bundle.js"></script>
</body>
</html>
A.jsx & B.jsx :
var A = React.createClass({
componentDidMount: function(){
ReactDOM.render(
<B />,
document.getElementById('container')
);
},
render: function(){
return (
<div>Hello World, I'm A.</div>
)
}
});
var B = React.createClass({
render: function(){
return (
<div>Hello World, I'm B.</div>
)
}
});
app.jsx:
ReactDOM.render(
<A />,
document.getElementById('container')
);
Can you reproduce your issue in a jsfiddle? https://jsfiddle.net/L3zn8dws/
The real question is why are you calling ReactDOM.render
from within a lifecycle method? You're trying to mount a new component at the node that the current component is mounted at, which seems like an anti-pattern.
You should use a root parent component to manage which component renders, instead of trying to re-mount at the root. If you absolutely have to have multiple React roots (which you should have a really good reason for) you should be using some sort of helper system manage this:
https://facebook.github.io/react/blog/2015/10/01/react-render-and-top-level-api.html#helpers
f you have multiple React roots, or a single root that gets deleted over time, we recommend that you always create your own wrapper API. These will all look slightly different depending on what your outer system looks like. For example, at Facebook we have a system that automatically ties into our page transition router to automatically call unmountComponentAtNode.
Rather than calling ReactDOM.render() directly everywhere, consider writing/using a library that will manage mounting and unmounting within your application.
This seems like an unsupported pattern: you are trying to render something into a container that already contains another component whose lifecycles are currently being executed.
If you want B
to appear, include <B />
from A
's render output.
Most helpful comment
The real question is why are you calling
ReactDOM.render
from within a lifecycle method? You're trying to mount a new component at the node that the current component is mounted at, which seems like an anti-pattern.You should use a root parent component to manage which component renders, instead of trying to re-mount at the root. If you absolutely have to have multiple React roots (which you should have a really good reason for) you should be using some sort of helper system manage this:
https://facebook.github.io/react/blog/2015/10/01/react-render-and-top-level-api.html#helpers
Rather than calling ReactDOM.render() directly everywhere, consider writing/using a library that will manage mounting and unmounting within your application.