Javascript 以增量方式渲染子对象

Javascript 以增量方式渲染子对象,javascript,reactjs,Javascript,Reactjs,假设我有一个React元素,我需要呈现一个 我的代码目前看起来像 Parent = React.createClass({ getChildren() { var children = this.props.messages; // this could be 100's return children.map((child) => { return <FooBar c={child} />; });

假设我有一个React元素
,我需要呈现一个

我的代码目前看起来像

Parent = React.createClass({

    getChildren() {
        var children = this.props.messages; // this could be 100's
        return children.map((child) => {
        return <FooBar c={child} />;
      });
    },

    render() {
      return (
        <div>
          {this.getChildren()}
        </div>
      );
    }
 });
Parent=React.createClass({
getChildren(){
var children=this.props.messages;//这可能是100
返回children.map((child)=>{
返回;
});
},
render(){
返回(
{this.getChildren()}
);
}
});

当有100个子对象时,这非常慢,因为父对象等待所有子对象渲染。是否有一种解决方法以增量方式渲染子级,以便父级不必等待其所有子级渲染?

您可以一次获取一部分消息进行渲染,然后通过状态计数与更多子级一起排队进行进一步更新

对队列使用
requestIdleCallback
setTimeout
将允许您避免React的状态批处理拦截当前浏览器绘制,如果您直接从
componentDidUpdate

这里有一些东西可以让你走

const Parent = React.createClass({

  numMessagesPerRender = 10

  constructor(props) {
    super(props)
    this.state = {
      renderedCount: 0
    }
  }

  componentWillReceiveProps(props) {
    // must check that if the messages change, and reset count if you do
    // you may also need to do a deep equality of values if you mutate the message elsewhere
    if (props.messages !== this.props.messages) {
      this.setState({renderedCount: 0})
    }
  }

  getChildren() {
      // take only the current
      const children = this.props.messages.slice(0, this.state.renderedCount);
      return children.map(child => <FooBar c={child} />);
  },

  render() {
    return (
      <div>
        {this.getChildren()}
      </div>
    );
  }

  renderMoreMessagesPlease() {
    // you MUST include an escape condition as we are calling from `componentDidXYZ`
    // if you dont your component will get stuck in a render loop and crash
    if (this.state.renderedCount < this.props.messages.length) {
      // queue up state change until the frame has been painted
      // otherwise setState can halt rendering to do batching of state changes into a single
      // if your browser doesnt support requestIdleCallback, setTimeout should do same trick
      this.idleCallbackId = requestIdleCallback(() => this.setState(prevState => ({
        renderedCount: prevState.renderedCount + this.numMessagesPerRender
      })))
    }
  } 

  componentDidMount() {
    this.renderMoreMessagesPlease()
  }

  componentDidUpdate() {
    this.renderMoreMessagesPlease()
  }

  componentDidUnmount() {
    // clean up so cant call setState on an unmounted component
    if (this.idleCallbackId) {
      window.cancelIdleCallback(this.idleCallbackId)
    }
  }

});
const Parent=React.createClass({
numMessagesPerRender=10
建造师(道具){
超级(道具)
此.state={
RenderCount:0
}
}
组件将接收道具(道具){
//必须检查消息是否更改,如果更改,则重置计数
//如果在其他地方对消息进行变异,则可能还需要执行值的深度相等
if(props.messages!==this.props.messages){
this.setState({renderedCount:0})
}
}
getChildren(){
//只取电流
const children=this.props.messages.slice(0,this.state.renderdcount);
返回children.map(child=>);
},
render(){
返回(
{this.getChildren()}
);
}
RenderMemessagesPlease(){
//当我们从'componentDidXYZ'调用时,必须包含转义条件`
//如果不这样做,组件将卡在渲染循环中并崩溃
if(this.state.renderdcountthis.setState(prevState=>({
RenderCount:prevState.RenderCount+this.numMessagesPerRender
})))
}
} 
componentDidMount(){
这个.renderMemessagesPlease()
}
componentDidUpdate(){
这个.renderMemessagesPlease()
}
componentDidUnmount(){
//清理,以便无法在未安装的组件上调用setState
if(this.idleCallbackId){
window.cancelIdleCallback(this.idleCallbackId)
}
}
});

我认为解决这一问题的方法是窗口化,对不起,我忘了提及,但这是我已经实施的解决方案,但感觉不太正确,我想知道是否有更简单的解决方案。更好的解决方案可能更以用户界面为中心,通过这种方式,呈现的消息量与用户在任何时候实际看到的内容相关联,即如果用户需要滚动查看完整列表,则只呈现项目,直到它们变得不可见,然后使用滚动事件在状态中触发此额外消息计数。它将使用与此类似的机制,而是使用
requestAnimationFrame
在屏幕绘制之前进行拦截,测量渲染消息的大小,与可用的可见空间进行比较,并排队进行更多渲染,直到它们变得不可见