From 3111456aa2fa2000899e937bb4adc414c1511711 Mon Sep 17 00:00:00 2001 From: paranoidjk Date: Tue, 21 Feb 2017 14:52:47 +0800 Subject: [PATCH] refactor(carousel): use class syntax --- components/carousel/index.tsx | 102 ++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 48 deletions(-) diff --git a/components/carousel/index.tsx b/components/carousel/index.tsx index 79f08e5a13d..7c93d585081 100644 --- a/components/carousel/index.tsx +++ b/components/carousel/index.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import ReactTimerMixin from 'react-timer-mixin'; import Pagination from '../pagination'; import { View, @@ -10,28 +9,30 @@ import { import CarouselStyle from './style'; import CarouselProps from './PropsType'; -const Carousel = React.createClass({ - mixins: [ReactTimerMixin], - - getDefaultProps() { - return { - bounces: true, - infinite: false, - dots: true, - autoplay: false, - autoplayTimeout: 2.5, - selectedIndex: 0, - // vertical 目前只实现 pagination,内容 vertical 由于自动高度拿不到,暂时无法实现 - vertical: false, - styles: CarouselStyle, - }; - }, - - getInitialState() { +class Carousel extends React.Component { + + static defaultProps: CarouselProps = { + bounces: true, + infinite: false, + dots: true, + autoplay: false, + autoplayTimeout: 2.5, + selectedIndex: 0, + // vertical 目前只实现 pagination,内容 vertical 由于自动高度拿不到,暂时无法实现 + vertical: false, + styles: CarouselStyle, + }; + + private autoplayTimer; + private androidScrollEndTimer; + private scrollEndTimter; + + constructor(props) { + super(props); const { children, selectedIndex } = this.props; const count = children ? children.length || 1 : 0; const index = count > 1 ? Math.min(selectedIndex, count - 1) : 0; - return { + this.state = { width: 0, isScrolling: false, autoplayEnd: false, @@ -39,13 +40,18 @@ const Carousel = React.createClass({ selectedIndex: index, offset: { x: 0, y: 0 }, }; - }, + } componentDidMount() { this.autoplay(); - }, + } - loopJump() { + componentWillUnMount() { + clearTimeout(this.autoplayTimer); + clearTimeout(this.androidScrollEndTimer); + clearTimeout(this.scrollEndTimter); + } + loopJump = () => { // iOS 通过 contentOffet 可以平滑过度,不需要做处理 if (this.state.loopJump && Platform.OS === 'android') { const index = this.state.selectedIndex + (this.props.infinite ? 1 : 0); @@ -54,9 +60,9 @@ const Carousel = React.createClass({ (this.refs as any).scrollview.scrollTo({ x, y: 0 }, false); }, 10); } - }, + } - autoplay() { + autoplay = () => { const { children, autoplay, infinite, autoplayTimeout } = this.props; const { isScrolling, autoplayEnd, selectedIndex } = this.state; const count = children ? children.length || 1 : 0; @@ -66,16 +72,16 @@ const Carousel = React.createClass({ clearTimeout(this.autoplayTimer); - this.autoplayTimer = this.setTimeout(() => { + this.autoplayTimer = setTimeout(() => { if (!infinite && (selectedIndex === count - 1)) { // !infinite && last one, autoplay end return this.setState({ autoplayEnd: true }); } this.scrollNextPage(); }, autoplayTimeout * 1000); - }, + } - onScrollBegin(e) { + onScrollBegin = (e) => { this.setState({ isScrolling: true, }, () => { @@ -83,9 +89,9 @@ const Carousel = React.createClass({ this.props.onScrollBeginDrag(e, this.state, this); } }); - }, + } - onScrollEnd(e) { + onScrollEnd = (e) => { this.setState({ isScrolling: false }); // android incompatible if (!e.nativeEvent.contentOffset) { @@ -97,16 +103,16 @@ const Carousel = React.createClass({ this.updateIndex(e.nativeEvent.contentOffset); - this.setTimeout(() => { + this.scrollEndTimter = setTimeout(() => { this.autoplay(); this.loopJump(); if (this.props.onMomentumScrollEnd) { this.props.onMomentumScrollEnd(e, this.state, this); } }); - }, + } - onScrollEndDrag(e) { + onScrollEndDrag = (e) => { const { offset, selectedIndex } = this.state; const previousOffset = offset.x; const newOffset = e.nativeEvent.x; @@ -117,9 +123,9 @@ const Carousel = React.createClass({ isScrolling: false, }); } - }, + } - updateIndex(offset) { + updateIndex = (offset) => { let state = this.state; let selectedIndex = state.selectedIndex; let diff = offset.x - state.offset.x; @@ -156,9 +162,9 @@ const Carousel = React.createClass({ if (afterChange) { afterChange(selectedIndex); } - }, + } - scrollNextPage() { + scrollNextPage = () => { const { children, infinite } = this.props; const count = children ? children.length || 1 : 0; if (this.state.isScrolling || count < 2) { @@ -179,7 +185,7 @@ const Carousel = React.createClass({ // trigger onScrollEnd manually in android if (Platform.OS === 'android') { - this.setTimeout(() => { + this.androidScrollEndTimer = setTimeout(() => { this.onScrollEnd({ nativeEvent: { position: diff, @@ -187,9 +193,9 @@ const Carousel = React.createClass({ }); }, 0); } - }, + } - renderContent(pages) { + renderContent = (pages) => { const others = { onScrollBeginDrag: this.onScrollBegin, onMomentumScrollEnd: this.onScrollEnd, @@ -215,9 +221,9 @@ const Carousel = React.createClass({ {pages} ); - }, + } - renderDots(index) { + renderDots = (index) => { const { children, vertical, styles } = this.props; const positionStyle = vertical ? 'paginationY' : 'paginationX'; const flexDirection = vertical ? 'column' : 'row'; @@ -231,9 +237,9 @@ const Carousel = React.createClass({ total={count} /> ); - }, + } - onLayout(e) { + onLayout = (e) => { // for horizontal, get width, scollTo const props = this.props; const count = props.children ? props.children.length || 1 : 0; @@ -245,10 +251,10 @@ const Carousel = React.createClass({ offset: { x: offsetX, y: 0 }, }, () => { if (Platform.OS === 'android') { - this.refs.scrollview.scrollTo({ y: 0, x: offsetX }, false); + (this.refs as any).scrollview.scrollTo({ y: 0, x: offsetX }, false); } }); - }, + } render() { let state = this.state; @@ -285,7 +291,7 @@ const Carousel = React.createClass({ {dots && this.renderDots(this.state.selectedIndex)} ); - }, -}); + } +} export default Carousel;