工作中的那点事之 动画
AutoAnimate
AutoAnimate
可以零配置实现添加动画。
使用方法则是使用useAutoAnimate
hook,会返回第一个元素为ref
的数组。把该ref
放到想要添加动画的元素上即可。
1 2 3 4 5 6 7 8
| import { useAutoAnimate } from "@formkit/auto-animate/react";
function MyList() { const [animationParent] = useAutoAnimate(); return ( <ul ref={animationParent}>{/* 🪄 Magic animations for your list */}</ul> ); }
|
自动动画会应用于父元素(设置 auto animate 的 ref)的直属子元素。
官方的文档说是会应用于父元素及其直属父元素。但是直接移除父元素并不会触发动画。
- DOM 中添加了子元素。
- DOM 中的子元素被移除。
- 子元素在 DOM 中被移动
当发生上述三种情况的时候,会触发动画
例子
在官网的 demo 中加了一个直接移除父元素的情况。代码也比较简单易懂。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| import { useState } from "react"; import { useAutoAnimate } from "@formkit/auto-animate/react";
export default function App() { const [items, setItems] = useState([1, 2, 3]); const [parent, enableAnimations] = useAutoAnimate();
const add = () => setItems([...items, items.length + 1]); const remove = () => setItems((prev) => { prev.splice(1, 1); return [...prev]; });
const [visible, setVisible] = useState(true); const removeParent = () => { setVisible(false); };
return ( <> {visible ? ( <ul ref={parent}> {items.map((item) => ( <li key={item}>{item}</li> ))} </ul> ) : null}
<button onClick={add}>Add number</button> <button onClick={remove}>Rmove number</button> <button onClick={removeParent}>Rmove Parent</button> <button onClick={() => enableAnimations(false)}>Disable</button> </> ); }
|
效果:


图 1 中是启用 AutoAnimate 的效果,图 2 则是关闭后的效果。
React Transition Group
Transition 组件使用会把样式跟组件耦合在一起,使用也不是很方便。所以主要介绍一下CSSTransition
CSSTransition
使用方法跟 Vue 的transition
组件类似。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import { useRef, useState } from "react"; import { CSSTransition } from "react-transition-group"; import "./App.css";
export default function App() { const [visible, setVisible] = useState(false); const nodeRef = useRef(null);
return ( <div> <CSSTransition nodeRef={nodeRef} in={visible} timeout={200} unmountOnExit classNames="container" > <> <div ref={nodeRef}>I am CLZ!!!</div> <div>no transition</div> </> </CSSTransition>
<button type="button" onClick={() => setVisible(true)}> Click to Enter </button>
<button type="button" onClick={() => setVisible(false)}> Click to Leave </button> </div> ); }
|
nodeRef
: 需要转换的 don 元素的 React 引用
in
: CSSTransition
的children
是否显示
unmountOnExit
:触发exit
后,是否从 dom 树中移除。触发exit
的时间一般是in
对应的值修改为false
。
CSSTransition
还需要添加样式才能成功添加动画。类名的规则如下:
其中$$
为CSSTransition
的classNames
(这里的s
是因为还可以给每个阶段单独指定className
,具体查看官网。
$$-enter
: 触发enter
前的样式
$$-enter-active
:触发enter
后的样式。效果就是从$$-enter
过渡到$$-enter-active
的样式
$$-exit
: 触发exit
前的样式
$$-exit-active
:触发exit
后的样式。同$$-enter-active
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| .container-enter { transform: translateX(-100px); opacity: 0; } .container-enter-active { transform: translateX(0); opacity: 1; transition: all 200ms; } .container-exit { transform: translateX(0); opacity: 1; } .container-exit-active { transform: translateX(-100px); opacity: 0; transition: all 200ms; }
|
效果:
