Reputation: 439
I have one complex component, that is rendering a few seconds. This component contains large canvas with a lot of items. Is there any way how to render some icon during waiting on this Print
component?
render(){
const {data} = this.props;
return(
<Page>
<div className="item column-3" id="graphColumn">
{this.state.loading ? <img src={loadingIcon}/> : false}
<div className={this.state.loading ? "hidden" : "visible"}>
<Print channels={this.state.channels} readyToRender={this.readyRender.bind(this)}/>
</div>
</div>
</Page>
)
}
readyRender(){
this.setState({
loading: false
})
}
I tried to set display:none
during rendering, and after in componentDidMount
in Print
component set display:auto
, but this doesn't work.It take long time too. Any tips for solution?
Upvotes: 2
Views: 1273
Reputation: 59531
There are ways, but probably not in the sense you were hoping for.
React executes its rendering synchronously which means nothing else can be run in parallel. However, if you can control when a time-consuming render will be executed, you can add your waiting icon beforehand.
Here's an example:
var Demo = React.createClass({
getInitialState: function() {
return {loading: true};
},
componentDidMount: function() {
setTimeout(() => {
this.setState({loading: false});
}, 1000); //delay this to allow React to actually render the initial state. Can be set to just 10ms, but then font-awesome css doesn't load in time from CDN.
},
render: function() {
if(!this.state.loading) return <div>{this.simulateSlowRender()}</div>;
return <div><i className="fa fa-spinner fa-spin fa-fw" aria-hidden="true"></i> loading...</div>;
},
simulateSlowRender: function() {
let arr = new Array(10000000);
arr.push("done!"); //the last item prints "done".
return <div>{arr.map((item) => item)}</div>;
}
});
ReactDOM.render(
<Demo />,
document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
<div id="container"></div>
Warning: Note that this will "hang" your entire application until rendering is complete. Javascript animations are unlikely to work during that time.
Upvotes: 2