react-transition-group提供了用于定义动画的简单组件,该库并未定义样式本身,而是以有用的方式操作DOM,从而使过渡和动画的实现更加舒适。换言之,react-transition-group提供了一种更简单的动画和过渡方法。
安装
// npm
npm install react-transition-group --save
// yarn
yarn add react-transition-group
官方提供四个组件,分别为 Transition, CSSTransition,SwitchTransition, TransitonGroup。
Transition
Transition组件允许你使用简单的声明性API描述随时间从一个组件状态到另一个组件状态的转换。最常见的是,它被用于动画组件的挂载和卸载,但也可以用于描述就地转换状态。
注意:Transition是一个平台无关的基础组件。如果你在CSS中使用过渡,你可能会想要使用CSS过渡。它继承了Transition的所有特性,但包含了其他必要的特性,以更好地处理CSS过渡(因此该组件的名称)。
默认情况下Transition组件不会改变它呈现的组件的行为,它只跟踪组件的“进入”和“退出”状态。这取决于你赋予这些状态意义和效果。例如,当组件进入或退出时,我们可以向它添加样式。
在一个过渡中有四种主要状态:
- entering
- entered
- exiting
- exited
过渡状态通过in属性切换。当为true时,组件开始“Enter”阶段。在此阶段中,组件将从当前转换状态转移到转换期间的“进入”状态,然后在完成转换后再转移到“进入”状态。
import { Transition } from 'react-transition-group';
const duration = 300;
const defaultStyle = {
transition: `opacity ${duration}ms ease-in-out`,
opacity: 0,
}
const transitionStyles = {
entering: { opacity: 1 },
entered: { opacity: 1 },
exiting: { opacity: 0 },
exited: { opacity: 0 },
};
const Fade = ({ in: inProp }) => (
<Transition in={inProp} timeout={duration}>
{state => (
<div style={{
...defaultStyle,
...transitionStyles[state]
}}>
I'm a fade Transition!
</div>
)}
</Transition>
);
参数 | 说明 | 类型 | 默认值 | children | 可以使用一个函数来代替 React 元素,通过调用这个函数与当前过渡状态(‘enter’、‘enter’、‘exit’、‘exited’、‘unmount’),可用于将特定于代码的props应用于组件。 | Function | element | in | 用于显示组件;触发进入或退出状态。 | boolean | false | mountOnEnter | 默认情况下,子组件与父转换组件一起立即挂载。如果你想“延迟挂载”第一个in={true}上的组件,你可以设置mountOnEnter。在第一次进入转换之后,组件将保持挂载状态,即使在“退出”状态下也是如此,除非你还指定unmountOnExit。 | boolean | false | unmountOnExit | 默认情况下,子组件在达到“退出”状态后仍然挂载。如果你希望在组件退出后卸载组件,请设置unmountOnExit。 | boolean | false | appear | 通常,如果组件挂载时显示组件,则该组件不进行转换。如果你希望在第一个挂载集上进行转换,则显示为true,并且组件将在< transition >挂载后立即进行转换。 注意:没有特定的“显示”状态。appear只添加一个额外的enter转换。 | boolean | false | enter | 启用或禁用enter转换。 | boolean | true | exit | 启用或禁用exit转换。 | boolean | true | timeout | 转换的持续时间,单位为毫秒。 | number | { enter?: number, exit?: number, appear?: number } | addEndListener | 添加自定义转换结束触发器。使用正在转换的DOM节点和done回调调用。允许更细粒度的转换结束逻辑。注意:如果提供超时,仍将其用作回退。 | Function | onEnter | 在应用“输入”状态之前触发的回调。提供了一个额外的参数isAppearing,以指示是否在初始挂载上出现了enter阶段。 | Function(node: HtmlElement, isAppearing: bool) | function noop() {} | onEntering | 在应用“输入”状态中触发的回调。提供了一个额外的参数isAppearing,以指示是否在初始挂载上出现了entering阶段。 | Function(node: HtmlElement, isAppearing: bool) | function noop() {} | onEntered | 在应用“输入”状态之后触发的回调。提供了一个额外的参数isAppearing,以指示是否在初始挂载上出现了entered阶段。 | Function(node: HtmlElement, isAppearing: bool) | function noop() {} | onExit | 在应用“退出”状态之前触发的回调。 | Function(node: HtmlElement) -> void | function noop() {} | onExiting | 在应用“退出”状态中触发的回调。 | Function(node: HtmlElement) -> void | function noop() {} | onExited | 在应用“退出”状态后触发的回调。 | Function(node: HtmlElement) -> void | function noop() {} |
---|
CSSTransition
此Transition组件用于CSS动画过渡,灵感来源于ng-animate库。
CSSTransition:在组件淡入appear,进场enter,出场exit时,CSSTransition组件应用了一系列className名来对这些动作进行描述。首先appear被应用到组件className上,接着添加“active”类名来激活CSS动画。在动画完成后,原class改变为done表明组件动画已经应用完成并加载完成。
当组件的in属性变为true时,组件的className将被赋值为example-enter,并在下一刻添加example-enter-active的CSS class名。这些都是基于className属性的约定。即:原组件带有className="animate-rotate",则enter状态时,变为"animate-rotate-enter"。
//index.js
import React,{ Component } from 'react'
import CSSTransition from 'react-transition-group/CSSTransition'
import './css/index.css'
export default class App extends Component {
state = {
show: true
}
render () {
return (
<CSSTransition
in={this.state.show}
classNames='show'
timeout={300}
unmountOnExit>
{state => {
// console.log(state)
return (
<div className='circle' onClick={()=>this.setState(state=>({show: !state.show}))}>
show
</div>
)
}}
</CSSTransition>
)
}
}
//index.css
.circle {
margin: 2px;
width: 50px;
height: 50px;
position: absolute;
display: inline-block;
left: 100px;
box-shadow: 0px 1px 2px #999;
text-shadow: 0px 1px 2px #999;
line-height: 80px;
text-align: center;
color: white;
font-size: 10px;
}
.show-enter {
opacity: 0.01;
transform: scale(0.9) translateY(50%);
}
.show-enter-active {
opacity: 1;
transform: scale(1) translateY(0%);
transition: all 300ms ease-out;
}
.show-exit {
opacity: 1;
transform: scale(1) translateY(0%);
}
.show-exit-active {
opacity: 0.01;
transform: scale(0.9) translateY(50%);
transition: all 300ms ease-out;
}
参数 | 说明 | 类型 | 默认值 | in | 控制组件应用动画的属性值,通常将一个react的组件state赋值给它,通过改变state,从而开启和关闭动画。 | boolean | false | classNames | classNames[注意带s]属性用于当组件被应用动画时,不同的动画状态(enter,exits,done)将作为className属性的后缀来拼接为新的className。 如:className="fade"会被应用为fade-enter,fade-enter-active,fade-enter-done,fade-exit,fade-exite-active,fade-exit-done, fade-appear以及fade-appear-active.每一个独立的className都对应着单独的状态。 | string | { appear?: string, appearActive?: string, enter?: string, enterActive?: string, enterDone?: string, exit?: string, exitActive?: string, exitDone?: string, } | onEnter | 组件的回调函数,当组件enter或appear时会立即调用。 | Function(node: HtmlElement, isAppearing: bool) | onEntering | 组件的回调函数,当enter-active或appear-active时会立即调用。 | Function(node: HtmlElement, isAppearing: bool) | onEntered | 组件的回调函数,当组件的enter,appearclassName被移除时会立即调用。 | Function(node: HtmlElement, isAppearing: bool) | onExit | 当组件应用exit类名时,调用此函数。 | Function(node: HtmlElement) | onExiting | 当组件应用exit-active类名时,调用此函数。 | Function(node: HtmlElement) | onExited | 当组件exit类名被移除,且添加了exit-done类名时,调用此函数。 | Function(node: HtmlElement) |
---|
SwitchTransition
受vue转换模式启发的转换组件。当你想要控制状态转换之间的呈现时,可以使用它。基于所选模式和子节点的键(Transition或cstransition组件),SwitchTransition在它们之间进行一致的转换。
如果选择了out-in模式,则SwitchTransition会等待旧的子节点离开,然后插入新的子节点。如果选择了in-out模式,SwitchTransition将首先插入一个新的子节点,等待新的子节点进入,然后删除旧的子节点。
注意:如果你想让动画同时发生(也就是说,移除旧的子元素并同时插入新的子元素),你应该使用TransitionGroup。
function App() {
const [state, setState] = useState(false);
return (
<SwitchTransition>
<CSSTransition
key={state ? "Goodbye, world!" : "Hello, world!"}
addEndListener={(node, done) => node.addEventListener("transitionend", done, false)}
classNames='fade'
>
<button onClick={() => setState(state => !state)}>
{state ? "Goodbye, world!" : "Hello, world!"}
</button>
</CSSTransition>
</SwitchTransition>
);
}
.fade-enter{
opacity: 0;
}
.fade-exit{
opacity: 1;
}
.fade-enter-active{
opacity: 1;
}
.fade-exit-active{
opacity: 0;
}
.fade-enter-active,
.fade-exit-active{
transition: opacity 500ms;
}
参数 | 说明 | 类型 | 默认值 | mode | 过渡模式。out-in:首先将当前元素移出,然后在完成时将新元素移入。in-out:新元素首先转换进来,完成后,当前元素转换出去。 | out-in | in-out | children | 任何Transition 或者 CSSTransition组件. | element |
---|
TransitionGroup
组件在一个列表中管理一组转换组件(< transition >和< cstransition >)。与转换组件一样,是一个状态机,用于管理组件随时间的挂载和卸载。
下面的例子,当项目被删除或添加到TodoList时,内部的prop将由自动切换。
注意没有定义任何动画行为!列表项的动画方式取决于各个转换组件。这意味着你可以混合和匹配不同列表项的动画。
//index.js
import React,{ Component } from 'react'
import { CSSTransition, TransitionGroup } from 'react-transition-group'
import './css/index.css'
export default class App extends Component {
state = {
items: [
{ id: 1, text: 'Buy eggs' },
{ id: 2, text: 'Pay bills' },
{ id: 3, text: 'Invite friends over' },
{ id: 4, text: 'Fix the TV' },
]
}
render () {
const { items } = this.state
return (
<div className='container'>
<TransitionGroup className="todo-list">
{items.map(({ id, text }) => (
<CSSTransition
key={id}
timeout={500}
classNames="show"
unmountOnExit>
<div className="todo-list-item">
<button
className='cancle'
onClick={() => {
this.setState(state => ({
items: state.items.filter(
item => item.id !== id
),
}));
}}>
×
</button>
<span className='item-text'>{text}</span>
</div>
</CSSTransition>
))}
</TransitionGroup>
<button
className='add'
onClick={() => {
const text = prompt('Enter some text');
if (text) {
this.setState(state => ({
items: [
...state.items,
{ id: 1123, text },
],
}));
}
}}>
Add Item
</button>
</div>
)
}
}
//index.css
.show-enter {
opacity: 0.01;
}
.show-enter-active {
opacity: 1;
transition: all 300ms ease-out;
}
.show-exit {
opacity: 1;
}
.show-exit-active {
opacity: 0.01;
transition: all 300ms ease-out;
}
.container {
position: absolute;
top: 20px;
left: 100px;
padding: 20px;
border-radius: 5px;
box-shadow: 0 0 10px 1px rgb(202, 202, 202);
}
.todo-list {
border-radius: 5px;
box-shadow: 0 0 5px 1px rgb(202, 202, 202);
}
.todo-list-item {
height: 35px;
line-height: 35px;
padding: 0 10px;
border-bottom: 1px solid rgb(202, 202, 202);
}
.todo-list-item:last-of-type {
border-bottom: 0;
}
.item-text {
margin-left: 10px;
}
.cancle {
border: 0;
color: #fff;
background-color: #F04134;
border-radius: 3px;
box-shadow: 0 0 5px 1px rgb(202, 202, 202);
}
.add {
border: 0;
height: 30px;
line-height: 30x;
width: 120px;
margin-top: 15px;
font-size: 14px;
border-radius: 3px;
box-shadow: 0 0 5px 1px rgb(202, 202, 202);
}
参数 | 说明 | 类型 | 默认值 | component | default 'div' 也就是TransitionGroup渲染出来的标签为div,也可以就行更改,例如component="span" 渲染出来的就是span标签。如果使用React v16+并且想要避免div元素的换行,你可以传入component={null}。 | any | div | children | 其中给的组件,可以是字符串或者自定义组件等。 | any | appear | 为所有的child启用或禁用显示/appear动画。注意,指定此参数将覆盖在各个子转换上的任何默认设置。 | boolean | enter | 为所有的child启用或禁用进入/enter动画。注意,指定此参数将覆盖在各个子转换上的任何默认设置。 | boolean | exit | 为所有的child启用或禁用退出/exit动画。注意,指定此参数将覆盖在各个子转换上的任何默认设置。 | boolean | childFactory | 如果你需要在一个子节点离开时更新它可以提供一个childFactory来包装每个子节点,即使是那些将要离开的子节点。 | Function(child: ReactElement) -> ReactElement | child => child |
---|
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!