1. 背景介绍

公开用于定义进入和退出转换的简单组件。React Transition Group 不是像React-Motion那样的动画库,它本身不会为样式设置动画。相反,它公开了过渡阶段,管理类和组元素,并以有用的方式操作 DOM,使实际视觉过渡的实现更加容易。

1.1 安装

  1. # npm
  2. npm install react-transition-group --save
  3. # yarn
  4. 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 示例

  1. import { Transition } from 'react-transition-group';
  2. const duration = 300;
  3. const defaultStyle = {
  4. transition: `opacity ${duration}ms ease-in-out`,
  5. opacity: 0,
  6. }
  7. const transitionStyles = {
  8. entering: { opacity: 1 },
  9. entered: { opacity: 1 },
  10. exiting: { opacity: 0 },
  11. exited: { opacity: 0 },
  12. };
  13. const Fade = ({ in: inProp }) => (
  14. <Transition in={inProp} timeout={duration}>
  15. {state => (
  16. <div style={{
  17. ...defaultStyle,
  18. ...transitionStyles[state]
  19. }}>
  20. I'm a fade Transition!
  21. </div>
  22. )}
  23. </Transition>
  24. );

2.1.2 转换可以处于 4 种主要状态:

  • ‘entering’
  • ‘entered’
  • ‘exiting’
  • ‘exited’

过渡状态通过in属性切换。当true组件开始“进入”阶段时。在此阶段,组件将从其当前的过渡状态转移到’entering’过渡期间,然后在’entered’完成后进入该阶段。让我们看下面的例子(我们将使用 useState钩子):

  1. function App() {
  2. const [inProp, setInProp] = useState(false);
  3. return (
  4. <div>
  5. <Transition in={inProp} timeout={500}>
  6. {state => (
  7. // ...
  8. )}
  9. </Transition>
  10. <button onClick={() => setInProp(true)}>
  11. Click to Enter
  12. </button>
  13. </div>
  14. );
  15. }

单击按钮时,组件将切换到该’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类名来保持转换状态。

  1. function App() {
  2. const [inProp, setInProp] = useState(false);
  3. return (
  4. <div>
  5. <CSSTransition in={inProp} timeout={200} classNames="my-node">
  6. <div>
  7. {"I'll receive my-node-* classes"}
  8. </div>
  9. </CSSTransition>
  10. <button type="button" onClick={() => setInProp(true)}>
  11. Click to Enter
  12. </button>
  13. </div>
  14. );
  15. }

当in属性设置为true时,子组件将首先接收到 class example-enter,然后example-enter-active在下一个 tick 中添加 。 在CSSTransition 添加example-enter-active. 这是一个重要的技巧,因为它允许我们在它们之间转换example-enter, example-enter-active即使它们是一个接一个地立即添加的。最值得注意的是,这使我们可以为外观设置动画。

  1. .my-node-enter {
  2. opacity: 0;
  3. }
  4. .my-node-enter-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. }

-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 示例

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

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/

  1. const [items, setItems] = useState([
  2. { id: uuid(), text: 'Buy eggs' },
  3. { id: uuid(), text: 'Pay bills' },
  4. { id: uuid(), text: 'Invite friends over' },
  5. { id: uuid(), text: 'Fix the TV' },
  6. ]);
  7. <Container style={{ marginTop: '2rem' }}>
  8. <ListGroup style={{ marginBottom: '1rem' }}>
  9. <TransitionGroup className="todo-list">
  10. {items.map(({ id, text }) => (
  11. <CSSTransition
  12. key={id}
  13. timeout={500}
  14. classNames="item"
  15. >
  16. <ListGroup.Item>
  17. <Button
  18. className="remove-btn"
  19. variant="danger"
  20. size="sm"
  21. onClick={() =>
  22. setItems(items =>
  23. items.filter(item => item.id !== id)
  24. )
  25. }
  26. >
  27. &times;
  28. </Button>
  29. {text}
  30. </ListGroup.Item>
  31. </CSSTransition>
  32. ))}
  33. </TransitionGroup>
  34. </ListGroup>
  35. <Button
  36. onClick={() => {
  37. const text = prompt('Enter some text');
  38. if (text) {
  39. setItems(items => [
  40. ...items,
  41. { id: uuid(), text },
  42. ]);
  43. }
  44. }}
  45. >
  46. Add Item
  47. </Button>
  48. </Container>

2.4.2 参数详解

|

component

类型:any
默认:’div’
默认情况下呈现 a
。您可以通过提供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 来包装每个产物,即使是那些正在离开的产物。 |

更多请访问顶部官网