1. 背景介绍
公开用于定义进入和退出转换的简单组件。React Transition Group 不是像React-Motion那样的动画库,它本身不会为样式设置动画。相反,它公开了过渡阶段,管理类和组元素,并以有用的方式操作 DOM,使实际视觉过渡的实现更加容易。
1.1 安装
# npm
npm install react-transition-group --save
# yarn
yarn add react-transition-group
官网:http://reactcommunity.org/react-transition-group/
1.2 使用场景
- 页面切换动画,tab切换动画
- 涉及到转场动画效果的地方都可以使用该组件
2. 组件使用
- Transition 过渡
- CSSTransition css过渡
- SwitchTransition 切换转换
- TransitionGroup 过渡组
2.1 Transition
Transition 组件允许您使用简单的声明式 API描述随时间从一个组件状态到另一个组件状态的转换。最常见的是它用于动画组件的安装和卸载,但也可用于描述就地过渡状态。
注意:Transition是一个平台无关的基础组件。如果你在 CSS 中使用过渡,你可能想要使用它 CSSTransition 。它继承了 的所有特性Transition,但包含了与 CSS 过渡配合得很好所必需的附加特性(因此是组件的名称)。
默认情况下,Transition组件不会改变它呈现的组件的行为,它只跟踪组件的“进入”和“退出”状态。赋予这些状态以意义和效果取决于您。例如,我们可以在组件进入或退出时为其添加样式:
2.1.1 示例
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>
);
2.1.2 转换可以处于 4 种主要状态:
- ‘entering’
- ‘entered’
- ‘exiting’
- ‘exited’
过渡状态通过in属性切换。当true组件开始“进入”阶段时。在此阶段,组件将从其当前的过渡状态转移到’entering’过渡期间,然后在’entered’完成后进入该阶段。让我们看下面的例子(我们将使用 useState钩子):
function App() {
const [inProp, setInProp] = useState(false);
return (
<div>
<Transition in={inProp} timeout={500}>
{state => (
// ...
)}
</Transition>
<button onClick={() => setInProp(true)}>
Click to Enter
</button>
</div>
);
}
单击按钮时,组件将切换到该’entering’状态并在该状态下停留 500 毫秒( 的值timeout),然后最终切换到’entered’。
什么时候in发生false同样的事情,除了状态从 移动 ‘exiting’到’exited’。
2.1.3 参数详解
children
类型:Function | element 必需的 |
function可以使用子元素代替 React 元素。此函数使用当前转换状态 ( ‘entering’, ‘entered’, ‘exiting’, ‘exited’) 调用,可用于将特定于上下文的属性应用于组件。 |
---|---|
in
| 类型:boolean
默认:false | 显示组件;触发进入或退出状态 |
|
mountOnEnter
| 类型:boolean
默认:false | 默认情况下,子组件与父Transition组件一起立即挂载。如果您想在第一个组件上“延迟安装”组件,in={true}您可以设置mountOnEnter. 在第一次进入转换之后,组件将保持安装状态,即使在“退出”时,除非您还指定unmountOnExit. |
|
unmountOnExit
| 类型:boolean
默认:false | 默认情况下,子组件在达到状态后保持挂载’exited’状态。unmountOnExit如果您希望在组件退出后卸载组件,请设置它。 |
|
timeout
| 类型:number | { enter?: number, exit?: number, appear?: number }
- appear默认值为enter
- enter默认为0
- exit默认为0
| 过渡的持续时间,以毫秒为单位。除非提供,否则必填addEndListener。 |
|
enter
| 类型:boolean
默认:true | 启用或禁用输入转换。 |
|
exit
| 类型:boolean
默认:true | 启用或禁用退出转换。 |
|
addEndListener
| 类型:Function | 添加自定义转换结束触发器。使用过渡 DOM 节点和done回调调用。允许更细粒度的转换结束逻辑。如果提供,超时仍用作后备。 |
更多请访问顶部官网
2.2 CSSTransition
建立在 Transition 组件之上,因此它继承了Transition的所有属性。
2.2.1 示例
CSSTransitionappear在, enter, 和exit过渡状态期间应用一对类名。应用第一个类,然后应用第二个-active类以激活 CSS 过渡。转换后,应用匹配的-done类名来保持转换状态。
function App() {
const [inProp, setInProp] = useState(false);
return (
<div>
<CSSTransition in={inProp} timeout={200} classNames="my-node">
<div>
{"I'll receive my-node-* classes"}
</div>
</CSSTransition>
<button type="button" onClick={() => setInProp(true)}>
Click to Enter
</button>
</div>
);
}
当in属性设置为true时,子组件将首先接收到 class example-enter,然后example-enter-active在下一个 tick 中添加 。 在CSSTransition 添加example-enter-active. 这是一个重要的技巧,因为它允许我们在它们之间转换example-enter, example-enter-active即使它们是一个接一个地立即添加的。最值得注意的是,这使我们可以为外观设置动画。
.my-node-enter {
opacity: 0;
}
.my-node-enter-active {
opacity: 1;
transition: opacity 200ms;
}
.my-node-exit {
opacity: 1;
}
.my-node-exit-active {
opacity: 0;
transition: opacity 200ms;
}
-active类表示您想要动画到哪些样式,因此transition仅向它们添加声明很重要,否则转换可能不会按预期运行!当过渡是对称的时,这可能并不明显,即-enter-active与 相同时-exit,如上面的示例(减去transition),但在更复杂的过渡中变得明显。
注意:如果您正在使用该 appear 属性,请确保也为.appear-类定义样式。
2.2.2 参数详解
classNames
类型:string | { appear?: string, appearActive?: string, appearDone?: string, enter?: string, enterActive?: string, enterDone?: string, exit?: string, exitActive?: string, exitDone?: string, } 默认:’’ |
在组件出现、进入、退出或完成过渡时应用于组件的动画类名。可以提供一个名称,每个阶段都会加上后缀,例如classNames=”fade” - fade-appear, fade-appear-active,fade-appear-done - fade-enter, fade-enter-active,fade-enter-done - fade-exit, fade-exit-active,fade-exit-done |
---|---|
继承Transition的参数,详细可查看 2.1.3
更多请访问顶部官网
2.3 SwitchTransition
当您想控制状态转换之间的渲染时,可以使用它。根据选择的模式和作为Transition和CSSTransition组件的子键,SwitchTransition在它们之间进行一致的转换。
如果out-in选择了该模式,则SwitchTransition等待直到旧的产物离开,然后插入一个新产物。如果in-out选择该模式,则SwitchTransition先插入一个新的产物,等待新的产物进入,然后移除旧的产物。
注意:如果您希望动画同时发生(即同时删除旧的产物并插入新的产物),您应该使用 TransitionGroup 。
2.3.1 示例
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;
}
2.3.2 参数详解
mode
类型:’out-in’|’in-out’ 默认:’out-in’ |
过渡模式。 out-in:当前元素先转出,完成后,新元素转入。 in-out:新元素先转入,完成后,当前元素转出。 |
---|---|
children
| 类型:element | 任何Transition或CSSTransition组件。 |
2.4 TransitionGroup
该
组件管理列表中的一组转换组件( 和 )。与过渡组件一样, 它是一个状态机,用于随时间管理组件的安装和卸载。
注意
不定义任何动画行为!列表项的确切动画方式取决于各个转换组件。这意味着您可以在不同的列表项中混合和匹配动画。
2.4.1 示例
demo:https://00rqyo26kn.csb.app/
const [items, setItems] = useState([
{ id: uuid(), text: 'Buy eggs' },
{ id: uuid(), text: 'Pay bills' },
{ id: uuid(), text: 'Invite friends over' },
{ id: uuid(), text: 'Fix the TV' },
]);
<Container style={{ marginTop: '2rem' }}>
<ListGroup style={{ marginBottom: '1rem' }}>
<TransitionGroup className="todo-list">
{items.map(({ id, text }) => (
<CSSTransition
key={id}
timeout={500}
classNames="item"
>
<ListGroup.Item>
<Button
className="remove-btn"
variant="danger"
size="sm"
onClick={() =>
setItems(items =>
items.filter(item => item.id !== id)
)
}
>
×
</Button>
{text}
</ListGroup.Item>
</CSSTransition>
))}
</TransitionGroup>
</ListGroup>
<Button
onClick={() => {
const text = prompt('Enter some text');
if (text) {
setItems(items => [
...items,
{ id: uuid(), text },
]);
}
}}
>
Add Item
</Button>
</Container>
2.4.2 参数详解
component
类型:any 默认:’div’ |
。您可以通过提供component属性来更改此行为。如果您使用 React v16+ 并希望避免包装 元素,您可以传入component={null}. 如果包装 div 破坏了您的 css 样式,这将很有用。 |
---|---|
children
| 类型:any | 一组
虽然此组件适用于多个Transition或CSSTransition 子组件,但有时您可能希望有一个转换子组件,其中包含您想要转换的内容以及在您更改它时(例如路线、图像等)。在这种情况下,您可以更改key当您更改其内容时,过渡组件的属性,这将导致 TransitionGroup产物退出和重新进入。 |
|
appear
| 类型:boolean | 为所有产物启用或禁用出现动画的便利属性。请注意,指定这将覆盖在单个子转换上设置的任何默认值。 | |
enter
| 类型:boolean | 为所有产物启用或禁用输入动画的便利属性。请注意,指定这将覆盖在单个子转换上设置的任何默认值。 | |
exit
| 类型:boolean | 一个方便的属性,可以为所有产物启用或禁用退出动画。请注意,指定这将覆盖在单个子转换上设置的任何默认值。 | |
childFactory
| 类型:Function(child: ReactElement) -> ReactElement
默认:child => child | 您可能需要在产物退出时对其应用响应式更新。这通常是通过使用来完成的,cloneElement但是在现有子元素的情况下,该元素已被删除并且消费者无法访问。
如果您确实需要在产物离开时对其进行更新,您可以提供一个childFactory 来包装每个产物,即使是那些正在离开的产物。 |
更多请访问顶部官网