最近在写react,实现了一个轮播图功能,才对react组件和状态更多一点的了解。
实现的功能是图片自动轮播,当鼠标移入图片时停止轮播,点击左右箭头进行平滑移动,底部小圆点进行标识,轮播图随屏幕大小变化。具体是这样一个结构。
class Slide extends React.Component {
constructor(...args) {
super(...args)
this.state = {
slideUrl: [],
index: 0,
liWidth: document.body.clientWidth,
posLeft: 0
}
}
/*
重置图片宽度
*/
onWindowResize() {
let liWidth2 = document.body.clientWidth;
this.setState({
liWidth: liWidth2
})
}
componentDidMount() {
this.setState({
slideUrl: [
{
'imageUrl': img1
},
{
'imageUrl': img2
},
{
'imageUrl': img3
}
, {
'imageUrl': img4
},
{
'imageUrl': img5
}
],
index: 0,
})
window.addEventListener('resize', this.onWindowResize.bind(this));
this.tick();
}
/**
* 组件即将卸载时调用。一般在componentDidMount注册的监听事件需要在该方法中注销删除,以免不必要的错误.
* @return void
*/
componentWillUnmount() {
//在组件即将销毁的时候取消resize的监听
window.removeEventListener('resize', this.onWindowResize.bind(this));
this._isMounted = false;
clearInterval(this.play)
}
/*轮播的功能*/
turn(direction) {
var index = this.state.index;
this._isMounted = true;
if (direction === 'left') {
index++
index = index >= this.state.slideUrl.length ? 0 : index;
} else if (direction === 'right') {
index--
index = index < 0 ? this.state.slideUrl.length - 1 : index;
}
if (this._isMounted) {
this.setState({
posLeft: -this.state.liWidth * (index),
index: index
}, () => {
this.state.index = index
})
}
}
/*定时器*/
tick() {
this.play = setInterval(() => {
this.turn('left');
}, 1000)
}
over() {
clearInterval(this.play)
}
render() {
const bannerList = this.state.slideUrl;
let arr = [];
for (let i = 0; i < bannerList.length; i++) {
arr[i] = <span className= {this.state.index === i ? 'circle active' : 'circle'} key={i}></span>
}
return (<div className="banner"
style={{
width: this.state.liWidth
}}
onMouseOver={this.over.bind(this)}
onMouseOut={this.tick.bind(this)}
>
<ul className='bannerUl' style={{
'left': this.state.posLeft,
width: this.state.liWidth * this.state.slideUrl.length,
Transition: 'all 0.4s',
WebkitTransition: 'all 0.4s', // note the capital 'W' here
msTransition: 'all 0.4s' // 'ms' is the only lowercase vendor prefix
}}>
{
bannerList.map((value, key) => {
return (<li key={key} style={{
width: this.state.liWidth
}}><img src={value.imageUrl}/></li>)
})
}
</ul>
<div className="ban_btn">
<span onClick={this.turn.bind(this, 'left')}>左</span>
<span onClick={this.turn.bind(this, 'right')}>右</span>
</div>
<div className='circles'>
{arr }
</div>
</div>
)
}
}
export default Slide;
小提示
1·如果不在render()中使用某些东西,它就不应该在状态中
2·它将使用 this.setState() 来更新组件局部状态
3·构造函数是唯一能够初始化 this.state 的地方。
4因为 this.props 和 this.state 可能是异步更新的,你不应该依靠它们的值来计算下一个状态。
5如果列表可以重新排序,我们不建议使用索引来进行排序,因为这会导致渲染变得很慢。如果你想要了解更多
6 行内的style样式命名是驼峰式命名