Разметки на анимации группы реагирования и перехода - PullRequest
0 голосов
/ 16 октября 2018

Я пытаюсь ознакомиться с react-transition-group, но у меня возникают некоторые проблемы.В простом компоненте, который отображает текущий счетчик и анимирует отображаемое значение на increment или decrement при вводе нового значения, он смещает предыдущее, что создает неожиданный эффект.Вероятно, это происходит потому, что новый элемент с непрозрачностью 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;
}

Я хочу добиться следующего поведения: при увеличении / уменьшении отображаемый счетчик исчезает, а новый добавляется после того, как текущий еще не существует.

1 Ответ

0 голосов
/ 16 октября 2018

Вероятно, это происходит потому, что новый элемент с непрозрачностью 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;
}

без группы переходов реагирования

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;
}
...