仅 jQuery 和 ReactJS 动画

Posted

技术标签:

【中文标题】仅 jQuery 和 ReactJS 动画【英文标题】:jQuery and ReactJS ONLY animations 【发布时间】:2015-09-29 23:33:54 【问题描述】:

我只需要使用 jQuery 动画,请不要提及过渡。

这是我的代码库

var CommentForm = React.createClass(

    componentWillUnmount: function(cb) 
        console.log('hiding')
        jQuery(this.getDOMNode()).slideUp('slow', cb);
        console.log((this.getDOMNode()))
    ,

    componentDidMount: function() 

        jQuery(this.getDOMNode()).hide().slideDown('slow');

        if (this.props.autofocus) 
            jQuery(this.refs.commentArea.getDOMNode()).focus();
        

    ,

    render: function() 
        return (
            <div>
                <div className="panel-footer" ref="commentComponent">
                    <form role="form">
                        <div className="form-group">
                            <textarea className="form-control" placeholder="Say something nice!" ref="commentArea"></textarea>
                        </div>
                        <div className="pull-right">
                            <button className="btn btn-default btn-md" type="button"><span className="fa fa-comment"></span> Comment</button>
                        </div>
                        <div className="clearfix"></div>
                    </form>
                </div>
            </div>
        );
    

);

如您所见,我可以在组件安装时添加一个很棒的动画,但我不能像代码中提到的那样使用动画卸载组件。

任何想法如何仅使用 jQuery 来做到这一点?和 Reactjs 组件生命周期?

【问题讨论】:

你可以创建一个jsFiddle吗?在不久的将来,我可能会遇到这种完全相同的情况,因此,我想现在尝试解决它。请用它创建一个 jsFiddle。 【参考方案1】:

这是我尝试使用过于简单的演示来解决此问题。

jsFiddle

javascript

var Container = React.createClass(
    onClicked: function() 
        console.log('Container.onClicked');
        if(this.state.isShowing)
            this.refs.myHelloWorld.hide();
         else 
            this.setState( isShowing: true );
        
    ,
    onAnimationComplete: function() 
        console.log('Container.onAnimationComplete');
        this.setState( isShowing: false );
    ,
    getInitialState: function() 
        return  isShowing: false ;
    ,
    render: function() 
        var helloWorld = this.state.isShowing ? <Hello name="World!" onComplete=this.onAnimationComplete ref="myHelloWorld" /> : '';
        return (
            <div id="container">
                <MyButton onButtonClicked=this.onClicked/>
                helloWorld
            </div>
        );
    
);

var MyButton = React.createClass(
    render: function() 
        return <button onClick=this.props.onButtonClicked>Toggle</button>;
    
);

var Hello = React.createClass(
    hide: function() 
        console.log('Hello.hide');
        var that = this;
        $(React.findDOMNode(this)).stop(true).fadeOut(
            duration: 1200,
            complete: function() 
                that.props.onComplete();
            
        );
    ,
    componentDidMount: function() 
        console.log('Hello.componentDidMount');
        $(React.findDOMNode(this)).stop(true).hide().fadeIn(1200);
    ,
    componentWillUnmount: function() 
        console.log('Hello.componentWillUnmount');
    ,
    render: function() 
        return <div>Hello  this.props.name </div>;
    
);
React.render(<Container />, document.body);

您已经发现,使用 componentDidMount 将任何子组件 in 动画到主视图并不是很困难生命周期事件。

但是,当我们想要从主视图中为子组件设置动画时,这样做会很棘手,因为对应的 componentWillUnmount 生命周期事件触发我们的视图实际上已经卸载并且在此之前没有可用的事件可供我们使用。即使有,我们也必须手动从其内部或从主视图中删除我们的子组件。我最初想使用 React.unmountComponentAtNode 来做同样的事情,但后来想出了另一种方法。

解决方案是先从主视图向子组件发送一个回调,作为稍后使用的参数。然后,我们调用子组件的另一个方法,该方法将动画 组件的 DOM 节点本身。最后,当动画完成时,我们将触发我们之前收到的相同回调。

希望这会有所帮助。

附:这种方法不受 jQuery 的 animate() 和相关方法的严格限制,而是可以用于任何其他基于 JS 的动画库(我正在查看我最喜欢的 GSAP ;)),只要它们在动画完成时触发回调(并且 GSAP 提供了 plethora 其中的一个)。

更新 #1:

哇哇哇哇!

碰巧的是,我更多地挖掘 ReactJS,尤其是它的动画部分,看看我发现了什么,他们暴露了一个 low-level API for transition events

所以我们之前试图用我们自己的回调来完成的事情,以及我们的props 对象维护对 etc 的引用,事实证明,它可以使用这个 API 本身来完成。

目前我不确定我是否真的非常喜欢它,因为我还没有在实际项目中实现这两种技术,但我很高兴我们现在有可用的选项。我们可以使用内部 API,也可以按照前面的建议编写自己的解决方案。

看看这个修改后的 jsFiddle 做同样的事情,但这次使用了内部回调,例如 componentWillEntercomponentWillLeave。

【讨论】:

是的,塔希尔干得好,感谢分享 GSAP,IT 看起来很棒: @Sahan:你必须看看我刚刚在上面添加的 Update #1:。不要忘记打开开发者工具的console 窗口以查看触发回调的顺序。 Tahir,感谢您的更新 :),是的,我认为该更新在现阶段运行良好且解决方案更清洁。让我们一起去吧? 是的。我认为如果有一个 API 可以做我们之前尝试做的几乎相同的事情,那么使用它是有意义的。无需重新发明***。告诉我进展如何。 我不久前还在另一个线程上发布了similar answer,您可能也对此感兴趣。

以上是关于仅 jQuery 和 ReactJS 动画的主要内容,如果未能解决你的问题,请参考以下文章

ReactJS SyntheticEvent stopPropagation() 仅适用于 React 事件?

Jquery 动画仅适用于一个元素

ReactJs

JQuery - 动态 CSS 动画更改仅在我离开浏览器窗口并返回时发生

jQuery动画(显示隐藏,淡入淡出,滑动)

Redux/Flux(使用 ReactJS)和动画