react to create a carousel assembly

Create a carousel assembly

issues that need resolving:

  • Ensure the correctness of the incoming props parameter format
  • React operation DOM elements created in the React
  • When the state of the switching component, for the setIntervalfunction of the operation to ensure that no error

Problem solving
props parameter prop-typespacket format set parameters and default settings props, props to ensure the accuracy of

Use react provided refattributes to manipulate dom element attributes react created

Call generated in a different hook function setIntervaland clearance setIntervalfunction

componentDidMount() {
   this.scoll();	// 执行核心函数,运行轮播器,在其内部将setInterval赋值给this.timer
}

// 解决组件状态改变setInterval函数报错问题 
componentWillReceiceProps(){
    clearInterval(this.timer); //清除之前的轮播函数中的定时器
    setTimeout(()=>{
       this.scroll();   // 重新执行轮播函数 
    },0);
}

Although this method can achieve the effect, but will complain when the component is destroyed rebuilt. Improved methods are as follows:

componentWillReceiveProps(){
    if(this.timer !== undefined){
        setTimeout(() => {
            clearInterval(this.timer); // 卸载定时函数
            this.scoll();
        },0);
    }else{
        this.scoll();
    }   
}			

The actual code is as follows

import React, {Component} from 'react';
import {Link} from 'react-router-dom';
import PropTypes from 'proptypes';
import Style from './Banner.module.css';

const defaultProps = {
    lists: []
};

class Banner extends Component{
    scoll = () => {
        var i = 0;
        var j = 0;
        var num = this.props.lists.length;
        if(num > 1){
            this.refs.banner.style.width = (num+1)*100+'vw';
            let btns = document.getElementById('bannerBtn')
                .querySelectorAll('li');
            this.timer = setInterval(function () {
                if(i>num){
                    this.refs.banner.style.transition = 'all 0s ease';
                    i=0;
                }else{
                    this.refs.banner.style.transition = 'all 1s ease';
                }
                this.refs.banner.style.left = -i*100+'vw';
                if((j > num-1) || (i === num) || (i===0)){
                    j=0;
                }
                btns.forEach((btn,index)=>{
                    if(index === j){
                        btn.style.background = '#fafafa';
                    }else{
                        btn.style.background = 'transparent';
                    }
                });
                i++;
                j++;
            }.bind(this),2000);
        }
    };

    componentDidMount() {
        // 组件渲染完执行
        this.scoll();
    }

    componentWillReceiveProps() {
        // props发生改变时执行
        if(this.timer !== undefined){
            setTimeout(() => {
                clearInterval(this.timer); // 卸载定时函数
                this.scoll();
            },0);
        }else{
            this.scoll();
        }
    }

    componentWillUnmount() {
        // 组件被卸载或销毁时执行
        clearInterval(this.timer); // 卸载定时函数
    }

    render() {
        var imgs = this.props.lists.map((list,index)=>{
            return (
	            <Link to={list.url} key={index}>
	            	<img src={list.img} alt=''/>
	            </Link>
	        );
        });
        var first = this.props.lists.length > 1 ?
            <Link to={this.props.lists[0].url}>
                <img src={this.props.lists[0].img} alt='' />
            </Link>
            :'';
        var btns = this.props.lists.map((list,index)=>{
            if(index===0){
                return <li style={{background: '#fafafa'}} key={index}></li>;
            }else{
                return <li key={index}></li>;
            }
        });

        return (
            <div className={Style.banner} onClick={this.scroll}>
                <div className={Style.bannerMain} ref="banner">
                    {imgs}
                    {first}
                </div>
                <div className={Style.btn}>
                    <ul id='bannerBtn'>
                        {btns}
                    </ul>
                </div>
            </div>
        );
    }
}

Banner.defaultProps = defaultProps;
Banner.propTypes = {
    lists: PropTypes.array
};

export default Banner;

Do not like do not spray

Guess you like

Origin blog.csdn.net/wang19970228/article/details/95220352