- react-transition-group 是 React 官方实现的,用于操作过渡效果的组件库,它不像 React-Motion 动画库,并没有给我们提供一些预置的动画效果
- 该组件库提供了 4 个组件,方便开发者对元素动画的各个阶段进行监控,如
入场动画、开始动画和离开动画 - 这 4 个组件的上手成本极低,且提供的功能足矣完成各种复杂的动画特效
Transition 组件
- 默认情况下,Transition 组件不会改变它呈现的组件的行为,它只跟踪组件动画的
进入和退出状态,由开发者来赋予这些状态的实际意义和展现效果 - 下面介绍 Transition 组件常用的 API
- children:func
- 一个函数,该函数接收当前动画的转换状态,返回页面实际需要渲染的子组件
- 转换状态分为两类,进入状态 和 离开状态
- 'entering' 当前为进入动画的展示中
- 'entered' 当前为进入动画的最终状态
- 'exiting' 当前为离开动画的展示中
- 'exited' 当前为离开动画的最终状态
<Transition in={this.state.in} timeout={150}>
{state => (
<MyComponent className={`my-${state}`} />
)}
</Transition>
-
in:boolean
- 接收动画触发的状态,为 true 时触发 进入动画,为 false 时触发 离开动画
-
appear:boolean
- 默认情况下,子组件在第一次挂载时,不管 in 的值为什么,组件都不会触发 进入动画
- 如果想要子组件展示类似 入场动画 的效果,需要将 appear 与 in 都设置为 true
-
timeout:number
- 动画的持续时间,单位为毫秒,可以一次设置所有状态的动画时间,也可以单独设置每个状态的动画时间
timeout={500}
// or
timeout={{
appear: 500,
enter: 300,
exit: 500,
}}
- addEndListener:func
- 自定义 transition 结束的触发器,它允许开发者自定义更加细腻的动画结束逻辑
- 其接收动画中的 dom 节点和一个动画结束的回调函数
addEndListener={(node, doneCallBack) => {
// use the css transitionend event to
// mark the finish of a transition
node.addEventListener('transitionend', doneCallBack);
}}
- 各个动画阶段的钩子
- 开始动画的三个钩子,均接收一个回调函数
Function(node: HtmlElement, isAppearing: bool) -> void,回调函数接收 2 个参数,第一个参数为当前元素的 dom 节点,第二个参数表示当前动画是否为元素初次挂载时发生 - onEnter:在动画状态变为 entering 之前调用
- onEntering:在动画状态变为 entering 之后调用
- onEntered:在动画状态变为 entered 之后调用
- 离开动画的三个钩子,均接收一个回调函数
Function(node: HtmlElement) -> void,回调函数仅接收当前元素的 dom 节点 - onExit:在动画状态变为 exiting 之前调用
- onExiting:在动画状态变为 exiting 之后调用
- onExited:在动画状态变为 exited 之后调用
- 开始动画的三个钩子,均接收一个回调函数
CSSTransition
- 该组件继承自 Transition 组件,继承了 Transition 的所有 API
- CSSTransition 组件在 Transition 提供的 开始动画 和 退出动画 的基础上,增加了 入场动画
- 支持更加细分的动画的各个阶段,以开始动画为例,CSSTransition 会在其子组件的 class 上依次添加 *-enter, *-enter-active, *-enter-done
- enter 表示开始动画的初始阶段
- enter-active 表示开始动画的激活阶段
- enter-done 表示开始动画的结束阶段,也是样式的持久化展示阶段
<CSSTransition in={flag} timeout={150}>
<MyComponent />
</CSSTransition>
- CSSTransition 增加的 API
- classNames
- 有两种使用方法,一种是提供一个统一的前缀字符串,它会自动给每个阶段的 class 名称加上这个前缀,另一种是提供一个对象,自己定义每个阶段的 class 名称
- classNames
classNames="my"
// or
classNames={{
appear: 'my-appear',
appearActive: 'my-active-appear',
appearDone: 'my-done-appear',
enter: 'my-enter',
enterActive: 'my-active-enter',
enterDone: 'my-done-enter',
exit: 'my-exit',
exitActive: 'my-active-exit',
exitDone: 'my-done-exit',
}}
SwitchTransition
- SwitchTransition 组件是受 vue 过渡模式的启发而诞生的,也是继承自 Transition 组件
- 当我们想要控制状态转换之间的渲染时,就可以使用 SwitchTransition
- SwitchTransition 需要使用 Transition 或 CSSTransition 包裹需要渲染到页面的组件,来当做它的 children
<SwitchTransition>
<CSSTransition
key={state}
addEndListener={
(node, doneCallBack) =>
node.addEventListener("transitionend", doneCallBack)
}
classNames='my'
>
<MyComponent />
</CSSTransition>
</SwitchTransition>
- SwitchTransition 增加的 API
- mode:'out-in' | 'in-out'
- out-in: 表示 SwitchTransition 需要等待 old child 离开,然后插入 new child
- in-out: 表示 SwitchTransition 需要等待插入 new child,然后移除 old child
- mode:'out-in' | 'in-out'
TransitionGroup
- 顾名思义,TransitionGroup 是来管理多个元素的动画效果,上面介绍的组件都是控制单个元素的动画效果
- TransitionGroup 就像是一个状态机,可以管理子组件的挂载状态和卸载状态的动画
<TransitionGroup>
{list.map(({ id }) => (
<CSSTransition
key={id}
timeout={500}
classNames="my"
>
<MyComponent key={id}/>
</CSSTransition>
))}
</TransitionGroup>
- TransitionGroup 新增的 API
- component
- 在默认情况下,TransitionGroup 会被渲染为一个 div,如果想要避免这样的行为,可以传入 null,
component={null} - appear
- 控制子组件是否展示 入场动画,默认为 true,它接收的值会覆盖掉子组件上对应的设置
- enter
- 控制子组件是否展示 开始动画,默认为 true,它接收的值会覆盖掉子组件上对应的设置
- exit
- 控制子组件是否展示 结束动画,默认为 true,它接收的值会覆盖掉子组件上对应的设置