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?