javascript - Non blocking render in ReactJS -
i'm learning reactjs , trying build application on it.
when i'm trying modify state , render, page freezing , can't until render finished when components become huge.
i found can use shouldcomponentupdate
optimize code, question comes me is: can make render procedure non blocking? , can tell user page processing heavy loading executions , please wait or maybe show progress of execution? or if user can cancel render, example, live editor, if user edit content of editor, "preview" section stop rendering old content , trying render new content without blocking editor ui?
here's heavy loading example code:
<!doctype html> <html> <head> <meta charset="utf-8" /> <title>react tutorial</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.1/react.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.1/react-dom.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script> </head> <body> <div id="content"></div> <script type="text/babel"> var box = react.createclass({ render: function() { return ( <div>box</div> ); } }); var commentbox = react.createclass({ getinitialstate: function() { return {box_count: 5}; }, heavyloadrender: function() { this.setstate({box_count: 40000}); }, render: function() { var render_box = []; (var i=0; i<this.state.box_count; i++) { render_box.push(<box />); } return ( <div> {render_box} <button onclick={this.heavyloadrender}>start</button> </div> ); } }); reactdom.render( <commentbox />, document.getelementbyid('content') ); </script> </body> </html>
when press start
, page freeze , no response until box
rendered. possible add button named cancel
user can cancel render , clear boxes?
this great question, , perfect use case settimeout
can schedule update next round of event loop.
rather store number of components render, store array of components, , render them directly. jsfiddle
var commentbox = react.createclass({ getinitialstate: function() { return { boxes: [<box key="first" />] }; }, heavyloadrender: function() { settimeout(() => { if (this.state.boxes.length < 50000) { this.setstate({ boxes: this.state.boxes.concat(<box key={this.state.boxes.length} />) }) this.heavyloadrender() } }) }, render: function() { return ( <div> <button onclick={this.heavyloadrender}>start</button> {this.state.boxes} </div> ) } })
update:
if want show state once array filled up, don't display until hits size:
this did not work:
{ this.state.boxes.length === 50000 && this.state.boxes }
hope not lost though! use style!
<div style={{ display: this.state.boxes.length === 50000 ? 'block' : 'none' }}> { this.state.boxes } </div>
if want increase speed, can push more item per settimeout
var newboxes = [] (var = 0; < 5; i++) { newboxes.push(<box />) } this.setstate({ boxes: this.state.boxes.concat(newboxes) })
updated fiddle. think whole class of problems going take time perform. in batches of 10,000 basic box component doesn't block , throw loading spinner there.
Comments
Post a Comment