【问题标题】:Layout breaks on react-transition-group animationreact-transition-group 动画的布局中断
【发布时间】:2019-03-20 09:03:52
【问题描述】:

我正在尝试熟悉react-transition-group,但遇到了一些问题。在一个简单的组件中,它显示当前计数器并在incrementdecrement 上为显示的值设置动画,当输入新值时,它会移动前一个值,从而产生突然的效果。这可能是因为具有不透明度0 的新元素进入圆顶并且两个值同时显示。

整个组件如下所示:

import React, { Component } from "react";
import { TransitionGroup, CSSTransition } from "react-transition-group";

import "./App.css";

class App extends Component {
  state = {
    progress: 0
  };
  incr = () => {
    this.setState({
      progress: this.state.progress + 1
    });
  };
  decr = () => {
    this.setState({
      progress: this.state.progress - 1
    });
  };
  render() {
    return (
      <div className="App">
        <TransitionGroup>
          <CSSTransition
            in={true}
            appear={true}
            key={this.state.progress}
            timeout={2000}
            classNames="slide"
          >
            <div key={this.state.progress}>{this.state.progress}</div>
          </CSSTransition>
        </TransitionGroup>
        <button onClick={this.decr}>decr</button>
        <button onClick={this.incr}>incr</button>
      </div>
    );
  }
}

export default App;

过渡类如下所示:

/* slide enter */
.slide-enter {
  opacity: 0;
  transform: scale(0.97) translateX(5px);
  z-index: 1;
}
.slide-enter.slide-enter-active {
  opacity: 1;
  transform: scale(1) translateX(0);
  transition: opacity 3000ms linear 1000ms, transform 3000ms ease-in-out 1000ms;
}

/* slide exit */
.slide-exit {
  opacity: 1;
  transform: scale(1) translateX(0);
}
.slide-exit.slide-exit-active {
  opacity: 0;
  transform: scale(0.97) translateX(5px);
  transition: opacity 1500ms linear, transform 1500ms ease-out;
}
.slide-exit-done {
  opacity: 0;
}

我想实现以下行为:在递增/递减时,当前显示的计数器逐渐消失,而新的计数器在当前计数器不存在后淡入。

【问题讨论】:

    标签: javascript reactjs reactcsstransitiongroup


    【解决方案1】:

    这可能是因为不透明度为 0 的新元素进入圆顶,并且两个值同时显示。

    是的,就是这样。您可以使用 position: absolute 从文档流中删除元素,并且您可能还需要以某种方式补偿从文档流中删除这些元素的事实。

    <TransitionGroup>
      <CSSTransition
        in={true}
        appear={true}
        key={this.state.progress}
        timeout={2000}
        classNames="slide"
      >
        <div className="animating" key={this.state.progress}>
          {this.state.progress}
        </div>
      </CSSTransition>
    </TransitionGroup>
    

    CSS

    .animating {
      position: absolute;
    }
    
    button:first-of-type {
      margin-top: 50px;
    }
    

    没有 React 过渡组

    JS

    import React, { Component } from "react";
    import "./App.css";
    
    class App extends Component {
      state = {
        progress: 0,
        transition: "entering" /* entering | exiting */
      };
      instanceVariables = {
        temporaryProgress: 0,
        timeoutId: null
      };
      animate = () => {
        clearTimeout(this.instanceVariables.timeoutId);
        this.instanceVariables.timeoutId = setTimeout(() => {
          this.setState({
            progress: this.instanceVariables.temporaryProgress,
            transition: "entering"
          });
        }, 1000);
        this.setState({
          transition: "exiting"
        });
      };
      incr = () => {
        this.instanceVariables.temporaryProgress += 1;
        this.animate();
      };
      decr = () => {
        this.instanceVariables.temporaryProgress -= 1;
        this.animate();
      };
      render() {
        return (
          <div className="App">
            <div className={`animate ${this.state.transition}`}>
              {this.state.progress}
            </div>
            <button onClick={this.decr}>decr</button>
            <button onClick={this.incr}>incr</button>
          </div>
        );
      }
    }
    
    export default App;
    

    CSS

    .animate {
      transition: opacity 1s linear, transform 1s ease-in-out;
    }
    
    .animate.exiting {
      transform: translateX(20px);
      opacity: 0;
    }
    
    .animate.entering {
      transform: translateX(0);
      opacity: 1;
    }
    

    【讨论】:

    • 感谢您的回答!但是有没有办法延迟退出动画,所以它会在新动画进入之前退出?在更复杂的布局中,我认为将absolute 赋予元素会破坏很多东西。谢谢!
    • position: absolute 正是我为 my app shell layout 所做的(它使用 React Transition Group 进行路由转换)。如果你只希望一次出现一个元素,那么最好不要使用 React Transition Group,因为你真的不需要它。你可以使用普通的 React。
    • 如果我只想将退出元素的不透明度从 1 设置为 0,反之亦然以进入元素,我将如何实现这一点?我现在正在与布局作斗争,以使我想要过渡的元素成为绝对的,但到目前为止它还不起作用,所以任何关于我如何在没有过渡组的情况下做到这一点的建议都非常受欢迎!再次感谢,这意味着很多
    • @DimitryIvashchuk 当然,我已经更新了我的答案以包含一个示例。
    • 感谢您的帮助和建议,我会根据他们的努力使其工作!
    猜你喜欢
    • 2020-07-04
    • 1970-01-01
    • 2019-01-17
    • 2019-01-17
    • 2015-10-02
    • 1970-01-01
    • 1970-01-01
    • 2018-04-03
    • 2019-07-07
    相关资源
    最近更新 更多