I have the following code, which is a react component rendering a huge component. As long as the huge component has not been finished with rendering, a loading indicator is shown.
import * as React from "react";
import ReactDOM from "react-dom";
import {HUGEComponent} from "./huge.tsx";
class App extends React.Component<{}, {loading: boolean}> {
constructor(props: {}) {
super(props);
this.state = {loading: true};
}
componentDidMount() {
setTimeout(() => this.setState({loading: false}), 0);
}
render() {
return this.state.loading ? <p>Loading...</p> : <HUGEComponent />;
}
}
ReactDOM.render(<App />, document.getElementById("root"));
The setTimeout
function inside componentDidMount
ensures, that the state update is happening only after the HUGEComponent
has been loaded (I used 10000 paragraphs of lorem ipsum as HUGEComponent
). Without setTimeout
, the state is updated immediately and the loading indicator is not shown.
So my question is, why does that work with setTimeout
? I know, that it pushes the state update to the message queue, which will therefore be executed after all other stuff has been done. But because a ternary operator (lazy evaluation) is used, actual rendering of HUGEComponent
should wait until the state has been updated, so that the state update occurs before rendering it, but that seems to be not true. The state is actually not updated as long as <HUGEComponent />
has not been evaluated. So why is <HUGEComponent />
evaluated before the state update despite the lazy evaluation in the ternary operator?