在 react 中通过使用 react-transition-group 实现过渡动画

CSSTransition

  • in:触发进入或者退出状态
  • 如果添加了unmountOnExit={true},那么该组件会在执行退出动画结束后被移除掉;
  • 当in为true时,触发进入状态,会添加-enter、-enter-acitve的class开始执行动画,当动画执行结束后,会移除两个class, 并且添加-enter-done的class;
  • 当in为false时,触发退出状态,会添加-exit、-exit-active的class开始执行动画,当动画执行结束后,会移除两个class,并 且添加-enter-done的class;
  • classNames:动画class的名称,决定了在编写css时,对应的class名称:比如card-enter、card-enter-active、card-enter-done;
  • timeout: 控制class添加和删除的时间。动画的时间是由CSS控制。
  • appear: 是否在初次进入添加动画(需要和in同时为true)
  • unmountOnExit:退出后卸载组件
  • CSSTransition对应的钩子函数:主要为了检测动画的执行过程,来完成一些JavaScript的操作
    • onEnter:在进入动画之前被触发;
    • onEntering:在应用进入动画时被触发;
    • onEntered:在应用进入动画结束后被触发;

示例

  1. import {useState} from 'react'
  2. import {CSSTransition} from 'react-transition-group'
  3. const CSSTransitionComponent = () => {
  4. const [inProp, setInProp] = useState(true);
  5. return (
  6. <div>
  7. <button type="button" onClick={() => setInProp(!inProp)}>
  8. Click to Enter
  9. </button>
  10. <CSSTransition
  11. appear
  12. in={inProp}
  13. timeout={200}
  14. classNames="my-node"
  15. unmountOnExit={true}>
  16. <div>
  17. "I'll receive my-node-* classes"
  18. </div>
  19. </CSSTransition>
  20. </div>
  21. );
  22. }
  23. export default CSSTransitionComponent
  1. .my-node-enter, .my-node-appear {
  2. opacity: 0;
  3. }
  4. .my-node-enter-active, .my-node-appear-active {
  5. opacity: 1;
  6. transition: opacity 200ms;
  7. }
  8. .my-node-exit {
  9. opacity: 1;
  10. }
  11. .my-node-exit-active {
  12. opacity: 0;
  13. transition: opacity 200ms;
  14. }
  15. .my-node-exit-done {
  16. opacity: 0;
  17. }

SwitchTransition

SwitchTransition 用于两个组件的切换

  1. const SwitchDemo = () => {
  2. const [state, setState] = useState(false)
  3. return (
  4. <div>
  5. <SwitchTransition>
  6. <CSSTransition
  7. key={state ? "Goodbye, world!" : "Hello, world!"}
  8. addEndListener={(node, done) => node.addEventListener("transitionend", done, false)}
  9. classNames='fade'
  10. >
  11. <button onClick={() => setState(state => !state)}>
  12. {state ? "Goodbye, world!" : "Hello, world!"}
  13. </button>
  14. </CSSTransition>
  15. </SwitchTransition>
  16. </div>
  17. )
  18. }
  19. export default SwitchDemo
  1. .fade-enter{
  2. opacity: 0;
  3. transform: translateX(100%);
  4. }
  5. .fade-exit{
  6. opacity: 1;
  7. transform: translateX(0);
  8. }
  9. .fade-enter-active{
  10. opacity: 1;
  11. transform: translateX(0);
  12. }
  13. .fade-exit-active{
  14. opacity: 0;
  15. transform: translateX(-100%);
  16. }
  17. .fade-enter-active,
  18. .fade-exit-active{
  19. transition: opacity 500ms, transform 500ms;
  20. }

TransitionGroup

TransitionGroup用来给一组组件添加动画,比如列表的添加和删除

  1. import React, { PureComponent } from 'react';
  2. import { CSSTransition, TransitionGroup } from 'react-transition-group';
  3. import './TransitionGroup.css';
  4. export default class TransitionGroupDemo extends PureComponent {
  5. constructor(props) {
  6. super(props);
  7. this.state = {
  8. names: ["coderwhy", "kobe", "lilei"]
  9. }
  10. }
  11. render() {
  12. return (
  13. <div>
  14. <TransitionGroup>
  15. {
  16. this.state.names.map((item, index) => {
  17. return (
  18. <CSSTransition key={item}
  19. timeout={500}
  20. classNames="item">
  21. <div>
  22. {item}
  23. <button onClick={e => this.removeItem(index)}>-</button>
  24. </div>
  25. </CSSTransition>
  26. )
  27. })
  28. }
  29. </TransitionGroup>
  30. <button onClick={e => this.addName()}>+name</button>
  31. </div>
  32. )
  33. }
  34. addName() {
  35. this.setState({
  36. names: [...this.state.names, "coderwhy"]
  37. })
  38. }
  39. removeItem(index) {
  40. // index indey indez
  41. this.setState({
  42. names: this.state.names.filter((item, indey) => index !== indey)
  43. })
  44. }
  45. }
  1. .item-enter {
  2. opacity: 0;
  3. transform: scale(.6);
  4. }
  5. .item-enter-active {
  6. opacity: 1;
  7. transform: scale(1);
  8. transition: opacity 300ms, transform 300ms;
  9. }
  10. .item-enter-done {
  11. color: red;
  12. }
  13. .item-exit {
  14. opacity: 1;
  15. transform: scale(1);
  16. }
  17. .item-exit-active {
  18. opacity: 0;
  19. transform: scale(.6);
  20. transition: opacity 300ms, transform 300ms;
  21. }
  22. .item-exit-done {
  23. opacity: 0;
  24. }

具体使用参看官方文档即可