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
setInterval
function of the operation to ensure that no error
Problem solving
props parameter prop-types
packet format set parameters and default settings props, props to ensure the accuracy of
Use react provided ref
attributes to manipulate dom element attributes react created
Call generated in a different hook function setInterval
and clearance setInterval
function
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