web-dev-qa-db-ja.com

React.jsを使用したslideUp()およびslideDown()アニメーション

SlideUp()およびslideDown()アニメーションで構成される反応コンポーネントを作成しました。 jQueryのslideupおよびslidedownメソッドを使用して実装しました。

反応アニメーションを使用してこの機能を実装する必要があります。

私はReactTransitionGroupReactCSSTransitionGroupについて読みました。説明の仕方は私に教えてくれました、DomNodeがコンポーネントにマウントされたとき、またはマウントを解除したとき(私が間違っていれば修正してください)にこの機能を実行できます。

私の質問は->どのようにjQueryを使用せずに反応してslideup()とslidedown()を行うかです。

https://jsfiddle.net/guc3yrm1/ については、このjsFiddleを参照してください

P.S-> jQueryと比べて、このリアクションアニメーション部分が少し難しいように思える理由を説明してください(私はjQueryの男です)

var Hello = React.createClass({
    getInitialState: function() {
        return {
            slide: false,
        }
    },
    slide: function() {
        if (this.state.slide) {
            $(this.refs.slide).slideDown();
            this.setState({
                slide: false
            });
        } else {
            $(this.refs.slide).slideUp();
            this.setState({
                slide: true
            });
        }
    },
    render: function() {
        return ( 
            <div>
                <input type = "button" value = "clickme" onClick = {this.slide}/> 
                <br />
                <br />
                <div className = "slide" ref="slide" >< /div>
            </div>
        );
    }
});

ReactDOM.render( < Hello name = "World" / > ,
    document.getElementById('container')
);
24

両方のアニメーションのAPIでアニメーションを実装できます。主な違いは次のとおりです。

ReactTransitionGroupは、ReactCSSTransitionGroupが構築されるAPIです。 2つの主な違いは、ReactTransitionGroupアニメーションはCSSではなくJavascriptで記述され、CSS遷移イベントに依存する代わりにアニメーションが完了すると呼び出されるコールバックが提供されることです。

私の結論は、単純なタスクにはCSSアニメーションを使用し、複雑なタスクにはJavascriptを使用することです。

たとえば、コンポーネントに静的な高さがある場合-以下に例を示すように、CSSを介して実装できます。ただし、幅/高さが動的な場合は、Javascriptを使用して行うことができます。 Javascriptの例では、アニメーションにVelocityライブラリを使用しています。 jQueryのアニメーションよりもパフォーマンスが優れています 。もちろん、自分でアニメーションを実装できますが、なぜ車輪を再発明するのですか?

両方のAPIでslideUp/slideDownを実装しました。以下をご覧ください。

(CSS)ReactCSSTransitionGroupを介した実装:

const CSSTransitionGroup = React.addons.CSSTransitionGroup;
const TransitionGroup = React.addons.TransitionGroup;

class Example extends React.Component{
    constructor(props) {
        super(props);
        this.state = { visible: false };
        this.handleClick = this.handleClick.bind(this)
    }

    handleClick() {
        this.setState({ visible: ! this.state.visible });
    }

    render() {
        return <div>
            <button onClick={this.handleClick}>{this.state.visible ? 'Slide up' : 'Slide down'}</button>
            <CSSTransitionGroup transitionName="example">
                { this.state.visible ? <div className='panel' /> : null }
            </CSSTransitionGroup>
        </div>
    }
}

React.render(<Example />, document.getElementById('container'));
.panel {
    width: 200px;
    height: 100px;
    background: green;
    margin-top: 10px;
}

.example-enter {
    height: 0px;
}

.example-enter.example-enter-active {
    height: 100px;
    -webkit-transition: height .3s ease;
}

.example-leave.example-leave-active {
    height: 0px;
    -webkit-transition: height .3s ease;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/react-with-addons.js"></script>
<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

JSFiddle-Reactスライドアップおよびスライドダウンアニメーション-CSS遷移グループ


(Javascript)ReactTransitionGroupを介した実装:

const TransitionGroup = React.addons.TransitionGroup;

class Example extends React.Component{
    constructor(props) {
        super(props);
        this.state = { visible: false };
        this.handleClick = this.handleClick.bind(this)
    }

    handleClick() {
        this.setState({ visible: ! this.state.visible });
    }

    render() {
        return <div>
            <button onClick={this.handleClick}>{this.state.visible ? 'Slide up' : 'Slide down'}</button>
                <TransitionGroup>
                    { this.state.visible ? <Accordion /> : null }
                </TransitionGroup>
            </div>
        }
    }

    class Accordion extends React.Component {
        componentWillEnter (callback) {
            const element = this.container.getDOMNode();
            Velocity(element, 'slideDown', { duration: 300 }).then(callback);
        }

        componentWillLeave (callback) {
            const element = this.container.getDOMNode();
            Velocity(element, 'slideUp', { duration: 300 }).then(callback);
        }

        setContainer(c) {
            this.container = c;
        }

        render() {
            return <div className="panel" ref={this.setContainer.bind(this)}>
                Lorem Ipsum is simply dummy text of the printing and typesetting industry.
                Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.
            </div>
        }
    }

React.render(<Example />, document.getElementById('container'));
.panel {
    background: green;
    margin-top: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/react-with-addons.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.4.3/velocity.min.js"></script>

<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

JSFiddle-Reactスライドアップおよびスライドダウンアニメーション-Javascript遷移グループ


クレジット:

31
Jordan Enev

(私のように)jQueryのslideDown/slideUpのリアクションの代替品を探してここに来た場合、react-slidedownは、使いやすい反応コンポーネントのようです。 githubページにはdemoexample codeがあります。

4
nachtigall

ジョーダン・エネフの要求に従って、私は彼のJSFiddleをフォークしました。

React Css Transition Groupをまったく必要としないソリューションです。私は個人的にクラス切り替えのファンです。

https://jsfiddle.net/fyuh32je/3/

(フィドルの全コード)

class Example extends React.Component{
    constructor(props) {
        super(props);
        this.state = { visible: 'panel' };
        this.handleClick = this.handleClick.bind(this)
    }

    handleClick() {
        this.setState({ visible: this.state.visible == 'panel'? 'panel visible' : 'panel' });
    }

    render() {
        return <div>
            <button onClick={this.handleClick}>{!this.state.visible == 'panel' ? 'Slide up' : 'Slide down'}</button>
                <div className={this.state.visible}>
                <p>This is some dynamic content!</p>
                <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
              </div>
        </div>
    }
}

React.render(<Example />, document.getElementById('container'));

そのような可視状態変数を使用するのは汚いことは知っていますが、私は仕事中で、あまり変更する時間があまりありませんでした。目に見えるクラスを使用して、アニメーションでdivコンテナを切り替えることに注意してください。

一般的に言えば。動的な高さコンテナは、cssのmax-height属性をハックして使用してアニメーション化できます。

2
noa-dev