2017-02-13 10 views
0

達成したいのは、トランジションアニメーションで不透明度を変更して、表示されている要素をスムーズに変更することです。トランジションでコンポーネントの小道具を変更する

私が構築するコンポーネントはスライダーです。現在のスライドでは、次のスライドのスライドの不透明度を1に、0に変更しています。

スライド部材の私の最初のバージョン

export class Slide extends React.PureComponent { 
    render() { 
    let { img, backgroundColor, active, ...props } = this.props; 
    const Wrapper = styled.div` 
     background-image: url(${img}); 
     background-color: ${backgroundColor}; 
     background-size: cover; 
     background-position: 50% 50%; 
     opacity: ${active ? 1 : 0}; 
     transition: opacity 1s; 
    `; 
    return (
     <Wrapper/> 
    ) 
    } 
} 

私が最初に考えた状態で現在のスライドインデックスを格納することでした。そこで、私のSlidesコンテナは、どのスライドが現在のものか知っていて、そのアクティブなプロパティをtrueに変更します。しかし、これはこのスライドを再レンダリングすると効果があり、トランジションは表示されません。最初の質問:なぜですか?

私は反応domで遊んでしまい、現在の要素の不透明度を手動で変更しました。

export default class Slider extends Component { 
    __slidesCount; 
    __current; 
    __refs = []; 

    constructor(props) { 
    super(props); 
    this.__current = 0; 
    this.__slidesCount = this.props.children.length 
    } 

    componentWillMount() { 
    // Save number of slides 
    } 

    nextSlide =() => { 
    let next = this.__current < this.__slidesCount - 1 ? this.__current + 1 : 0, 
     nextSlide = this.__refs[next], 
     currentSlide = this.__refs[this.__current]; 

    ReactDOM.findDOMNode(nextSlide).style['opacity'] = 1; 
    ReactDOM.findDOMNode(currentSlide).style['opacity'] = 0; 
    this.__current = next; 
    setTimeout(this.nextSlide, 3000) 
    }; 

    componentDidMount() { 
    // set timeout to run it after component mounting is finished 
    setTimeout(() => { 
     ReactDOM.findDOMNode(this.__refs[0]).style['opacity'] = 1; 
    }, 0); 
    // call function changing slide to next 
    setTimeout(this.nextSlide, 3000) 
    } 

    render() { 
    let { children, ...props } = this.props; 
    let slides = children.map((slide, index) => { 
     return React.cloneElement(slide, { ref: ref => this.__refs.push(ref) }) 
    }); 
    return (
     <SlidesWrapper {...props}> 
     {slides} 
     </SlidesWrapper> 
    ) 
    } 
} 

このソリューションについてどう思いますか?それを簡単にする方法はありますか? もちろん、私はjQueryを使いたくなく、外部CSSの使用を最小限に抑えたいと思います。

+0

ReactCSSTransitionGroupを試しましたか? – Vlado

+0

'ReactCSSTransitionGroup'について読んだのは、それが新しい要素やアンマウントされた要素に使われるということです。 'ReactCSSTransitionGroupはReactTransitionGroupに基づく高水準のAPIであり、ReactコンポーネントがDOMに入ったり出るときにCSSの遷移やアニメーションを簡単に実行できます。 https://facebook.github.io/react/docs/ animation.html – Darkowic

答えて

1

EDIT:はOPがStyled Componentsを使用していた、と彼はconst Wrapper...render()方法の内側に位置していたので、毎回render()が呼び出された新しいコンポーネントを作成していたことが判明しました。

Slideコンポーネントが更新されるたびにWrapperコンポーネントが再マウントされるため、コンポーネントの新しいインスタンスであり、したがって新しいHTML要素であるため、CSSの遷移は発生しません。 CodePen


ここでCSSの遷移がactive状態が小道具として渡された場合でも動作し、外部CSSなしでUIの状態を制御することをコンセプトの証明です。私は、不透明度を変更して、アクティブなスライドを切り替えるという同じ例を使って、動作することを示しました。

状態が変更されたときにSlideが再レンダリングされている場合は、このシーケンス全体を再レンダリングする可能性があります。おそらく、あなたのコンポーネントが削除され、再度追加されたり、何か他のものがあります。これを自分でデバッグするか、より多くのコードを提供して助けてください。

また、コメントに記載されているように、必要がある場合はReactCSSTransitionGroupを使用することができます。

+0

さて、なぜそれが私にとってうまくいかないのか分かりました。私はそれをテストし、私のスライドが単純なdivであれば動作します。しかし、 'styled.div'を返すと、それはしませんでした。それはコンポーネントのスタイルを変更するだけでなく、全体のdivを再レンダリングするようです。 – Darkowic

+0

よろしくお願いします。私は興味があります、どのような構文が 'styled.div'のものなのでしょうか?私はかつてそれを見たことがない。 –

+0

これは 'styled-components'ライブラリのコンポーネントです(https:// github)。com/styled-components/styled-components – Darkowic

関連する問題