react-transition-group 过渡动画库

react-transition-group 库可以帮助开发者方便地实现组件进入和退出的过渡动画。

React 曾为开发者提供过动画插件 react-addons-css-transition-group,后来改由社区维护,形成了现在的 react-transition-group 库。

安装:

npm install react-transition-group --save

主要组件:

react-transition-group 库主要包含四个组件:

Transition:

该组件是一个和平台无关的组件。

CSSTransition:

CSSTransition 是基于 Transition 组件构建的,通过在合适的时机添加、移除类名来实现过渡效果。

在前端开发中,一般是结合 CSS 来完成样式,所以通常使用 CSSTransition 来完成过渡动画效果。

属性:
  1. in:触发组件的 enter 或者 exit 状态。
    • 当 in 为 true 时,触发进入状态,会为组件添加 -enter-enter-active 的 class,开始执行动画;当动画执行结束后,会移除 -enter-enter-active 的 class,并且添加 -enter-dene 的 class。
    • 当 in 为 false 时,触发退出状态,会为组件添加 -exit-exit-active 的 class,开始执行动画;当动画执行结束后,会移除 -exit-exit-active 的 class,并且添加 -exit-dene 的 class。
  2. unmountOnExit:设置当组件处于 exited 状态时卸载组件。
  3. timeout:设置过渡动画的时间。
  4. classNames:要添加的动画的类名前缀。
    CSSTransition 执行过程中有三种状态:appear(初始状态)、enter(进入)、exit(退出)。这三种状态,需要定义对应的 CSS 样式:
    • 初始状态:对应的类名分别是 -appear-enter-exit
    • 开始执行动画,对应的类名分别是 -appear-active-enter-active-exit-active
    • 结束执行动画,对应的类名分别是 -appear-done-enter-done-exit-done
  5. appear:是否为初始状态添加动画。
钩子函数:
  1. onEnter:在进入动画执行之前被触发。
  2. onEntering:在进入动画开始执行时被触发。
  3. onEntered:在进入动画结束执行后被触发。
  4. onExit:在退出动画执行之前被触发。
  5. onExiting:在退出动画开始执行时被触发。
  6. onExited:在退出动画结束执行后被触发。

实现一个组件淡出淡入的动画效果。

// App.jsx
import {CSSTransition} from 'react-transition-group'
import './App.css'

class App extends PureComponent {
  state = {
    isShow: true,
  }
  render() {
    const {isShow} = this.state
    return (
      <>
      	<button onClick={() => this.setState({isShow: !isShow})}>切换</button>
      	
        {/* 使用 CSSTransition 包裹要设置过渡动画的 React 元素,会在合适的时机为 React 元素添加、移除类名来实现过渡效果 */}
        <CSSTransition in={isShow} unmountOnExit={true} timeout={2000} classNames='fade' appear onEnter={() => console.log('进入动画执行之前')}>
          <h1>过渡动画</h1>
        </CSSTransition>
      </>
    )
  }
}
// App.css
/* 初始动画,进入动画 */
.fade-appear, .fade-enter {
  opacity: 0;
}

.fade-appear-active, .fade-enter-active {
  opacity: 1;
  transition: opacity 2s ease;
}

/* 退出动画 */
.fade-exit {
  opacity: 1;
}

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

SwitchTransition:

实现两个组件切换的动画效果。

SwitchTransition 需要包裹 Transition 或者 CSSTransition,单个的组件的动画效果还是需要由 Transition 或者 CSSTransition 实现,两个组件切换的动画效果由 SwitchTransition 实现。

属性:
  1. mode:过渡的模式。
    • out-in:表示旧组件先移除,新组件再进入。
    • in-out:表示新组件先进入,旧组件再移除。

实现左侧退出一个组件,右侧进入一个组件的动画效果。

// App.jsx
import {SwitchTransition, CSSTransition} from 'react-transition-group'
import './App.css'

class App extends PureComponent {
  state = {
    isLogin: true,
  }
  render() {
    const {isLogin} = this.state
    return (
      <>
        {/* 使用 SwitchTransition 包裹 CSSTransition。mode 属性为 out-in,表示两个组件切换的模式是一个先出另一个再进 */}
        <SwitchTransition mode='out-in'>
          {/* 使用 CSSTransition 包裹要设置动画的 React 元素。需要设置不同的 key 属性 */}
          <CSSTransition key={isLogin ? 'login' : 'logout'} timeout={2000} classNames='translate'>
            <button onClick={() => this.setState({isLogin: !isLogin})}>
              {isLogin ? '登录' : '退出'}
            </button>
          </CSSTransition>
        </SwitchTransition>
      </>
    )
  }
}
// App.css
/* 进入动画 */
.translate-enter {
  transform: translateX(100px);
  opacity: 0;
}

.translate-enter-active {
  transform: translateX(0);
  opacity: 1;
  transition: all 2s ease;
}

/* 退出动画 */
.translate-exit {
  transform: translateX(0);
  opacity: 1;
}

.translate-exit-active {
  transform: translateX(-100px);
  opacity: 0;
  transition: all 2s ease;
}

TransitionGroup:

当有一组动画时,需要将这些 Transition 或者 CSSTransition 放入到一个 TransitionGroup 中来完成动画。

一般用于列表中元素的动画。

属性:
  1. component:TransitionGroup 最终被渲染成的元素。默认情况下会被渲染成 一个 div 元素,也可以传入 null 将不会被渲染成任何元素。
// App.jsx
import {TransitionGroup, CSSTransition} from 'react-transition-group'
import './App.css'

class App extends PureComponent {
  state = {
    books: [
      {
        id: 1,
        name: '你不知道的 JS',
        price: '99',
      }
    ],
  }

  handleAdd = () => {
    let books = [...this.state.books]
    books.push({
      id: new Date().getTime(),
      name: 'JS 高级程序设计',
      price: 88,
    })
    this.setState({books})
  }

  handleDelete = index => {
    let books = [...this.state.books]
    books.splice(index, 1)
    this.setState({books})
  }

  render() {
    const {books} = this.state
    return (
      <>
        {/* 使用 TransitionGroup 包裹一组想要实现动画的 React 元素 */}
        <TransitionGroup>
          {books.map((item, index) => (
            // 使用 CSSTransition 包裹真正想要实现动画的 React 元素。需要设置唯一的 key 属性
            <CSSTransition key={item.id} timeout={2000} classNames='fade'>
              <li>
                {item.name}: {item.price}
                <button onClick={() => this.handleDelete(index)}>删除</button>
              </li>
            </CSSTransition>
          ))}
        </TransitionGroup>
        <button onClick={this.handleAdd}>添加一本书</button>
      </>
    )
  }
}
/* 进入动画 */
.fade-enter {
  opacity: 0;
}

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

/* 退出动画 */
.fade-exit {
  opacity: 1;
}

.fade-exit-active {
  opacity: 0;
  transition: opacity 2s ease;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值