原文
https://blog.openreplay.com/how-to-add-animations-with-react-transition-group/
正文
如果你是一个React菜鸟,在你的应用中包含动画是一个非常困难的事情,毕竟有许多方法添加动画,一些相对于另一些方法具有很高的学习难度
在这篇文章,我介绍React Transition Group和如何使用他去添加/触发动画在你的React应用
甚至你是一个React菜鸟,你将有能力使用动画让你的应用变的更加动态,具有更好的用户体验。
先决条件
在我们开始学习之前,我推荐你有以下的先决条件
1.基础React知识
2.基础CSS知识
3.IDE编辑器
介绍 什么是What is React Transition Group
React Transition Group是由React开发团队自身开发的,本质上是一组组件指定React组件动画的挂载和卸载
需要明确的是,这不是一个css动画库,他只是暴露了过渡的阶段,可以更简单的管理class和处理动画当组件进入或者退出的时候
React Transition Group拥有四个组件,你可以使用这些组件帮助你管理或触发动画,
Transition、CSSTransition、SwitchTransition 、TransitionGroup
让我们一起看看他们
开始和安装
假设你已经有了React应用并已经初始化,让我们首先安装react-transition-group包
npm install react-transition-group
我们可以从该包中导入4个组件
import {Transition, CSSTransition, SwitchTransition, TransitionGroup} from "react-transition-group";
1.Transition 组件
现在让我们看看Transition 组件,他是一个追踪组件挂载和卸载的组件(进入和退出),需要强调的是,他追踪的一共有4种主要状态
entering 进入中
entered 已经进入完毕
exiting 退出中
exited 已经退出完毕
在我们的组件中,我们可以通过任何的值或副作用传递给这些状态来触发动画
在Transition 中非常重要的属性是in属性,这个属性可以在切换的时候进行控制,当组件正在进入中或退出中的状态,看看下面的小栗子
const duration = 300;
const defaultStyle = {
transition: `opacity ${duration}ms ease-in-out`,
opacity: 0,
padding: 20,
display: "inline-block",
backgroundColor: "#b3d0ff"
};
const transitionStyles = {
entering: { opacity: 0 },
entered: { opacity: 1 },
exiting: { opacity: 1 },
exited: { opacity: 0 },
};
function App() {
const [inProp, setInProp] = useState(false);
return (
<div>
<button onClick={() => setInProp(!inProp)}>Click to Show</button>
<Transition in={inProp} timeout={300}>
{(state) => (
<div
style={{
...defaultStyle,
...transitionStyles[state]
}}
>
I'm a component that gets a Fade transition!
</div>
)}
</Transition>
</div>
);
}
按钮将切换in属性,将会切换组件触发进入中和退出中的状态
timeout属性是触发进入中和退出中状态到达时长后设置为进入完毕或退出完毕状态
他也是过度的时间
让我们回顾一下,单击按钮的时候,in属性会切换,将设置组件为进入中状态,如果为true,或者退出中状态,当它为false状态时,一旦进入了状态,组件将会保留这种状态持续到timeout结束,他将自动切换为进入完毕或退出完毕的状态
上方代码展现了淡出动画,因为我们在transitionStyles指定了结果
2. CSSTransition 组件
该组件基于Transition组件,所以他继承了Transition 组件所有的属性,CSSTransition 组件对于你的过度状态,附加CSS动画很有用
首先,我们需要创建4个css class,在下方
.example-enter {
opacity: 0;
transform:translateX(-100%);
}
.example-enter-active {
opacity: 1;
transform:translateX(0);
transition: opacity 300ms, transform 300ms;
}
.example-exit {
opacity: 1;
transform:translateX(0);
}
.example-exit-active {
opacity: 0;
transform:translateX(-100%);
transition: opacity 300ms, transform 300ms;
}
让我解释每一个为什么这样做
1.example-enter当组件开始进入中的状态的时候附加
2.example-enter-active当组件开始进入中的状态到进入结束的状态时附加
3.example-exit当组件开始退出中的状态的时候附加
4.example-exit-active当组件开始退出中的状态到退出结束的状态时附加
现在,我们创建的组件如下
function Example() {
const [showMessage, setShowMessage] = useState(false);
return (
<div>
<Button onClick={() => setShowMessage(!showMessage)}>
Show Message
</Button>
<CSSTransition in={showMessage} timeout={300} classNames="example" unmountOnExit>
<p>Hello, I am a message that animates with CSSTransition!</p>
</CSSTransition>
</div>
);
}
结果如下
SwitchTransition组件
SwitchTransition组件是一个非常帅气的组件,允许你控制2个子组件之间的渲染,他有两种模式,out-in以及in-out
out-in是第一个子组件首先离开,然后下一个子组件再进来
in-out是下一个子组件先进来,然后第一个子组件再离开
通常一个SwitchTransition 被与Transition /CSSTransition 组件一起连用
让我们创造一个例子,使用了SwitchTransition以及CSSTransition 组件!
第一,我们先要有一些css
.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;
}
在这个例子,我们将使用out-in模式,我们的引用组件将如下所示
function App() {
const [state, setState] = useState(false);
return (
<SwitchTransition mode={"out-in"}>
<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>
);
}
结果如下
TransitionGroup组件
最后但是同样重要的是,我们还有一个TransitionGroup 组件,如同名字一样,这个组件不能处理动画自身,相反,他是Transition /CSSTransition 组件的组,管理挂载和卸载这些组件,在列表中
例如,我们一个水果数组,我想要列表的每一个项都有动画,当他出现的时候,首先,我会使用map函数展示每一个水果,每一个水果在列表中应该有一个CSSTransition 组件去处理他们独立的动画,我可以使用TransitionGroup 包裹这个列表
这个代码展示在下方
unction App() {
const [items, setItems] = useState([
'🍏 Apple',
'🍌 Banana',]);
const FRUITS = [
'🍏 Apple',
'🍌 Banana',
'🍍 Pineapple',
'🥥 Coconut',
'🍉 Watermelon',
'🍓 Strawberry',
'🍈 Melon',
'🥝 Kiwi',
'🍒 Cherry',
'🍑 Peach'
];
const handleAddFruit = () => {
const nextHiddenItem = FRUITS.find((i) => !items.includes(i));
if (nextHiddenItem) {
setItems((prev) => [ ...prev, nextHiddenItem]);
}
};
return (
<div className="App">
<TransitionGroup>
<h2>Shopping List</h2>
{items.map(( item, index ) => (
<CSSTransition key={index} timeout={500} classNames="fade">
<p>{item}</p>
</CSSTransition>
))}
<button onClick={handleAddFruit}>
Add Fruit
</button>
</TransitionGroup>
</div>
);
}
结果将战士每一个水果添加在列表中,同时展现出一个美好的动画~
总结
在本文中,我们介绍了该库的一些基础知识,我希望你学到了一些有价值的东西
React Transition Group是向React应用添加动画非常简单并具有高度的弹性的一种方法,如果你对CSS感到满意,创建令人惊叹的动画和实现通过使用 Transition Group.就不是困难的
感谢你的阅读,如果这个文章帮助你理解了React Transitiong Group请分享和给个关注,老铁双击666,干就完了
参考
https://reactcommunity.org/react-transition-group/
https://mui.com/components/transitions/