2016-05-16 105 views
3

我们想要显示一个循环幻灯片的图片,看起来像一个gif。当前结果在此网址可见:https://figuredevices.com与React.js循环图片幻灯片相关的性能问题

我们目前的做法是使用不透明显示或隐藏幻灯片:

class SlideShow extends React.Component { 

    constructor(props, context) { 
    super(props); 
    this.state = { 
     currentSlide: 0 
    }; 
    this.interval = null; 

    } 

    componentDidMount() { 
    this.interval = setInterval(this.transitionToNextSlide.bind(this), 200); 
    } 

    componentWillUnmount(){ 
    if(this.interval){ 
     clearInterval(this.interval); 
    } 
    } 

    transitionToNextSlide() { 

    let nextSlide = this.state.currentSlide + 1; 

    if (nextSlide == this.props.slides.length) { 
     nextSlide = 0; 
    } 
    this.setState({currentSlide: nextSlide}); 
    } 


    render() { 

    let slides = this.props.pictures.map((picture, idx) => { 
     let slideContainerStyle = { 
     opacity: this.state.currentSlide == idx ? 1 : 0 
     }; 
     return(
     <div style={slideContainerStyle} key={idx}> 
      <Slide picture={picture}/> 
     </div> 
    ); 
    }) 

    let containerStyle = { 
     width:'100%' 
    }; 

    return (
     <div style={containerStyle}> 
      {slides} 
     </div> 
    ); 

    } 

}; 

照片在五个加载五成this.props.picture。图片数量没有限制,我担心这个数字会增长。有两件事对我来说不太合适:

  • render方法中的映射操作每200ms遍历整个数组只改变两个css属性。
  • DOM是增长了不少大小,但大多数节点都隐藏

你能提出一个更好的办法,也许使用animationreact-motion

+0

为什么不只是一个''并更新'图片'道具每200毫秒? – Aaron

+0

如果你想保持不透明度过渡..你只需要两张幻灯片。用一个'next'道具来定位动画'',并且@Aaron说只是相应地改变道具。 – azium

+0

我没有看到任何不透明褪色,但是:是的:如果你想要一个过渡,你可以使用'ReactCSSTransitionGroup',并用当前图片替换''。 – Aaron

回答

0

您应该将所有图片保存为一个数组,并且每200毫秒增加一个数组索引。然后,而不是每一次显示所有的图片,只需让它显示当前索引处的图片。这是好多了,因为你只是返回一张照片,而不是一堆看不见的东西:)

注意:我无法测试这个,所以我不确定是否一切都是完全正确的语法正确,但这是总体思路。每200ms,增加slideIndex。然后,总是只返回一个div,只有你想看的一张图片。

class SlideShow extends React.Component { 

    constructor(props, context) { 
    super(props); 
    this.state = { 
     slideIndex; 
    }; 
    this.interval = null; 

    } 

    componentDidMount() { 
    this.interval = setInterval(this.transitionToNextSlide.bind(this), 200); 
    } 

    componentWillUnmount(){ 
    if(this.interval){ 
     clearInterval(this.interval); 
    } 
    } 

    transitionToNextSlide() { 
    this.setState({this.state.slideIndex: (this.state.slideIndex + 1) % this.props.slides.length}) 


    render() { 
    let containerStyle = { 
     width:'100%' 
    }; 

    return (
     <div style={containerStyle}> 
      <Slide picture={this.props.pictures[this.state.currentSlide]}/> 
     </div> 
    ); 
    } 
};