繁体   English   中英

ReactJS中的非阻塞渲染

[英]Non blocking render in ReactJS

我正在学习ReactJS并尝试在其上构建一些应用程序。

当我试图修改我的状态并进行渲染时,我的页面会冻结,并且在我的组件变得庞大时渲染完成之前无法执行任何操作。

我发现我可以使用shouldComponentUpdate来优化我的代码,但问题是:我能否使这个渲染过程无阻塞? 所以我可以告诉用户该页面正在处理一些繁重的加载执行,请等待或者显示执行的进度? 或者,如果用户可以取消渲染,例如,对于实时编辑器,如果用户编辑编辑器的内容,“预览”部分将停止渲染旧内容并尝试渲染新内容而不阻止编辑器UI?

这是重载示例代码:

 <!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 = []; for (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> 

当我按下“ Start ,页面将冻结,并且在呈现所有Box之前不会响应。 是否可以添加一个名为Cancel的按钮,用户可以取消渲染并清除所有框?

这是一个很好的问题,也是setTimeout的完美用例,它可以安排更新到下一轮事件循环。

而不是存储要渲染的组件数,而是存储组件数组,并直接呈现它们。 的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>
      )
    }
  })

更新:

如果只想在阵列填满后显示状态,则在达到该大小之前不要显示任何内容:

这不起作用:

{ this.state.boxes.length === 50000 && this.state.boxes }

希望不会丢失! 使用风格!

<div style={{ display: this.state.boxes.length === 50000 ? 'block' : 'none' }}>
  { this.state.boxes }
</div>

如果要提高速度,可以按每个setTimeout推送多个项目

var newBoxes = []
for (var i = 0; i < 5; i++) {
   newBoxes.push(<Box />)
}
this.setState({ 
  boxes: this.state.boxes.concat(newBoxes)
})

更新小提琴 我认为这类问题需要时间才能完成。 在10,000个批次中,基本的盒子组件不会阻塞,您可以轻松地将装载旋转器放在那里。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM