【问题标题】:Animation on unmount with React and react-transition-group使用 React 和 react-transition-group 卸载动画
【发布时间】:2019-01-17 03:12:44
【问题描述】:

我正在使用 React,我正在尝试使用 React-transition-group 创建一个 Fade 组件,以根据状态中存储的条件淡入和淡出元素:http://reactcommunity.org/react-transition-group/css-transition/

这就是我现在拥有的:

import React from "react";
import ReactDOM from "react-dom";
import { CSSTransition } from "react-transition-group";

import "./styles.css";

class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      mounted: false
    };
  }
  componentDidMount() {
    setTimeout(() => {
      this.setState({
        mounted: true
      });
    }, 10);
  }
  render() {
    return (
      <div className="root">
        <CSSTransition
          in={this.state.mounted}
          appear={true}
          unmountOnExit
          classNames="fade"
          timeout={1000}
        >
          {this.state.mounted ? (
            <div>
              <button
                onClick={() => {
                  this.setState({
                    mounted: !this.state.mounted
                  });
                }}
              >
                Remove
              </button>
              <div>COMPONENT</div>
            </div>
          ) : (
            <div />
          )}
        </CSSTransition>
      </div>
    );
  }
}

这里是 CSS

.fade-enter {
    opacity: 0;
    transition: opacity .5s ease;
}

.fade-enter-active {
    opacity: 1;
    transition: opacity .5s ease;
}

.fade-exit {
    opacity: 1;
    transition: opacity .5s ease;
}

.fade-exit-active {
    opacity: 0;
    transition: opacity .5s ease;
}

安装组件后,不透明度会在 0.5 秒内从 0 过渡到 1。但是当它卸载时,它没有动画:组件消失而没有过渡。

我用这个组件做了一个沙箱来测试它:https://codesandbox.io/s/k027m33y23 我确信这是一种常见情况,但我找不到在卸载时为组件设置动画的方法。如果有人有任何想法,将非常欢迎!

-- 编辑-- 正如@IPutuYogaPermana 所说,CSSTransition 中的条件渲染不是必需的。所以这个:

{this.state.mounted ? (
<div>
    <button
    onClick={() => {
        this.setState({
        mounted: !this.state.mounted
        });
    }}
    >
    Remove
    </button>
    <div>COMPONENT</div>
</div>
) : (
<div />
)}

应该是这样的:

<div>
    <button
    onClick={() => {
        this.setState({
        mounted: !this.state.mounted
        });
    }}
    >
    Remove
    </button>
    <div>COMPONENT</div>
</div>

组件将根据 CSSTransition 组件中的in 属性自动挂载或卸载。 这里是codesandbox中的最终代码:https://codesandbox.io/s/62m86nm7qw

【问题讨论】:

    标签: javascript reactjs css-animations react-transition-group


    【解决方案1】:

    这是意料之中的,因为随着状态的改变,动画还没有开始,但是孩子们已经走了。

    所以它就像神奇地瞬间消失。那么我们只需要隐藏它对吗?删除条件渲染。

    我检查了,动画完成后节点自动删除。所以不需要使用条件渲染。幸运的是!代码变成:

    import React from "react";
    import ReactDOM from "react-dom";
    import { CSSTransition } from "react-transition-group";
    
    import "./styles.css";
    
    class Example extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          logoIntro: true,
          mounted: false
        };
      }
      componentDidMount() {
        this.setState({
          mounted: true
        });
      }
      render() {
        return (
          <div className="root">
            <CSSTransition
              in={this.state.mounted}
              appear={true}
              unmountOnExit
              classNames="fade"
              timeout={1000}
            >
              <div>
                <button
                  onClick={() => {
                    this.setState({
                      mounted: !this.state.mounted
                    });
                  }}
                >
                  Remove
                </button>
                <div>SOME COMPONENT</div>
              </div>
            </CSSTransition>
          </div>
        );
      }
    }
    
    ReactDOM.render(<Example />, document.getElementById("root"));
    

    【讨论】:

    • 谢谢@IPutuYogaPermana 你的意思是“react-transition-group”不处理这种情况,我必须自己实现?很奇怪,因为是很常见的情况,对吧?
    • 好吧,实际上问题是因为子节点被删除了,甚至在动画开始之前。需要更好的解决方法。
    • 好的,我明白了。但是,除了这个解决方案之外,在卸载之前最常用的淡出动画方法是什么?
    • 我更新了我的答案,我才意识到,问题是因为子节点有条件渲染。只需删除条件渲染。所以当动画完成后,孩子会自动移除。
    • 我不熟悉 SO sn-ps 的方式。仅显示示例代码。如果这能解决您的问题,请将其标记为已接受的答案;)@AdCorrea
    猜你喜欢
    • 2023-03-25
    • 2018-02-06
    • 1970-01-01
    • 1970-01-01
    • 2020-07-04
    • 1970-01-01
    • 2018-02-09
    • 2018-04-03
    • 2019-07-07
    相关资源
    最近更新 更多