Create a broadcaster component in react

Keywords: React Attribute

Create a broadcaster component

Problems to be solved:

  • Make sure the format of the passed props parameter is correct
  • Manipulate the DOM elements created by React in React
  • Operation of setInterval function during component state switching to ensure no error is reported

Problem solving
The props parameter uses the prop types package to set the parameter format and the default props setting, so as to ensure the correctness of props.

Use the ref attribute provided by react to manipulate the dom element attributes created by react

Calling setInterval and clearing setInterval function in different hook functions

componentDidMount() {
   this.scoll();	// Execute the core function, run the carousel, and assign setInterval to this.timer
}

// Solve the problem of component state change setInterval function error 
componentWillReceiceProps(){
    clearInterval(this.timer); //Clear timer in previous carousel function
    setTimeout(()=>{
       this.scroll();   // Re execute the carousel function 
    },0);
}

Although this method can achieve the effect, it will report an error when the component is destroyed and rebuilt. The improvement methods are as follows:

componentWillReceiveProps(){
    if(this.timer !== undefined){
        setTimeout(() => {
            clearInterval(this.timer); // Unload timing function
            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() {
        // Component rendering finished execution
        this.scoll();
    }

    componentWillReceiveProps() {
        // Execute when props changes
        if(this.timer !== undefined){
            setTimeout(() => {
                clearInterval(this.timer); // Unload timing function
                this.scoll();
            },0);
        }else{
            this.scoll();
        }
    }

    componentWillUnmount() {
        // Execute when the component is uninstalled or destroyed
        clearInterval(this.timer); // Unload timing function
    }

    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;

No joy, no spray.

Posted by lipun4u on Thu, 31 Oct 2019 04:04:14 -0700