创建轮播器组件
需要解决的问题:
- 确保传入的props参数格式的正确性
- 在React中操作React创建的DOM元素
- 组件状态切换时,对于
setInterval
函数的操作,以确保不会报错
问题解决
props参数使用prop-types
包设置参数格式以及默认props的设置,确保props的正确性
使用react提供的ref
属性来操作react创建的dom元素属性
在不同的钩子函数中调用生成setInterval
和清除setInterval
函数
componentDidMount() {
this.scoll(); // 执行核心函数,运行轮播器,在其内部将setInterval赋值给this.timer
}
// 解决组件状态改变setInterval函数报错问题
componentWillReceiceProps(){
clearInterval(this.timer); //清除之前的轮播函数中的定时器
setTimeout(()=>{
this.scroll(); // 重新执行轮播函数
},0);
}
这种方法虽然可以实现效果,但当组件被销毁重建时会报错。改进方法如下:
componentWillReceiveProps(){
if(this.timer !== undefined){
setTimeout(() => {
clearInterval(this.timer); // 卸载定时函数
this.scoll();
},0);
}else{
this.scoll();
}
}
实际代码如下
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;
不喜勿喷