簡體   English   中英

使用 React 和 react-transition-group 卸載動畫

[英]Animation on unmount with React and react-transition-group

我正在使用 React,我正在嘗試使用 React-transition-group 創建一個Fade組件,以根據狀態中存儲的條件淡入和淡出元素: http ://reactcommunity.org/react-transition -組/css-過渡/

這就是我現在所擁有的:

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

這是預期的,因為隨着狀態的改變,動畫還沒有開始,但孩子們已經走了。

所以它就像神奇的瞬間消失。 那么我們只需要隱藏它吧? 刪除條件渲染。

我檢查過,動畫完成后節點自動刪除。 所以不需要使用條件渲染。 幸運的是! 代碼變成:

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"));

我創建了一個通用的WrapperComponent ,這樣您就可以對元素進行動畫處理,而不必總是一遍又一遍地編寫相同的東西。

import { useEffect, useState } from "react"
import { CSSTransition } from "react-transition-group"

export const MountAnimation = ({
  children,
  timeout = 300, // MATCH YOUR DEFAULT ANIMATION DURATION
  isVisible = false,
  unmountOnExit = true,
  classNames = "transition-translate-y", // ADD YOUR DEFAULT ANIMATION
  ...restProps
}) => {
  const [isMounted, setIsMounted] = useState(isVisible)
  useEffect(() => setIsMounted(isVisible), [isVisible])
  return (
    <CSSTransition
      in={isMounted}
      timeout={timeout}
      classNames={classNames}
      unmountOnExit={unmountOnExit}
      {...restProps}
    >
      <>{children}</>
    </CSSTransition>
  )
}

就像這樣使用它:

import { MountAnimation } from '../../path/to/component'

...

const [isElementVisible, setIsElementVisible] = useState(false)

return (
    <MountAnimation isVisible={isElementVisible}>
       // your content here
    </MountAnimation>

)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM