持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第21天,点击查看活动详情
Exposes simple components useful for defining entering and exiting transitions. React Transition Group is not an animation library like React-Motion, it does not animate styles by itself. Instead it exposes transition stages, manages classes and group elements and manipulates the DOM in useful ways, making the implementation of actual visual transitions much easier.
公开用于定义进入和退出转换的简单组件。 React Transition Group 不是像 React-Motion 那样的动画库,它本身不会为样式设置动画。相反,它公开了过渡阶段,管理类和组元素,并以有用的方式操作 DOM,使实际视觉过渡的实现更加容易。
文档:reactcommunity.org/react-trans…
网上的博客用法:www.jianshu.com/p/49fa164b9…
组件 | 说明 |
---|---|
Transition | 过渡组件 |
CSSTransition | 动画进入出入组件 |
SwitchTransition | 动画却换组件 |
TransitionGroup | 列表动画组件 |
Transition
The Transition component lets you describe a transition from one component state to another over time with a simple declarative API. Most commonly it's used to animate the mounting and unmounting of a component, but can also be used to describe in-place transition states as well.
Transition 组件允许您使用简单的声明式 API 描述随时间从一个组件状态到另一个组件状态的转换。最常见的是它用于动画组件的安装和卸载,但也可用于描述就地过渡状态
默认情况下,只跟踪组件的进入和退出状态。效果还要靠自己
There are 4 main states a Transition can be in:
'entering'
进入中'entered'
进入后'exiting'
离开中'exited'
离开后
属性
in
显示组件;触发进入或退出状态,默认false
。
timeout
动画时间
children
接收state
状态的函数组件或者元素
例子
import { useState } from "react";
import "./App.css";
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 },
};
function App() {
const [inProp, setInProp] = useState(false);
return (
<div className="App">
<header className="App-header">
{/* in 显示组件;触发进入或退出状态,默认false。 timeout 动画时间 */}
<Transition in={inProp} timeout={duration}>
{(state) => (
<div
style={{
...defaultStyle,
...transitionStyles[state],
}}
>
I'm a fade Transition!
</div>
)}
</Transition>
<button onClick={() => setInProp(!inProp)}>Click to Enter</button>
</header>
</div>
);
}
export default App;
默认是exited
,当in
为ture
时,进入 进入中 的状态,timeout
时间后变成 进入后 的状态
in
由true
变false
,则进入 离开中 状态,timeout
时间后变成 离开后 的状态
实现过程
- 先完成架构, 注入子组件传递动画状态。初始状态通过判断
in
得出是进入后或者离开后。
import React from 'react';
const ENTERING = 'entering'
const ENTERED = 'entered'
const EXITING = 'exiting'
const EXITED = 'exited'
class Transition extends React.Component {
constructor(props) {
super(props);
this.state = {
status: props.in ? ENTERED : EXITED
};
}
render() {
const { children } = this.props
const { status } = this.state
return (
children(status)
)
}
}
export default Transition
- 组件状态的变化是通过
in
来更改的,所以通过componentDidUpdate
去 监听,当in
为true
,状态要改为进入中,且 在 过渡时间后改成 进入后,反之。。。
componentDidUpdate() {
const { status } = this.state
const { in: nextIn } = this.props
console.log(this.props)
// 如果 in 为true,且 状态是离开后,那状态要改成进入中
if (nextIn) {
this.setState({
status: ENTERING
})
// 并且 要在 动画时间后改变状态
setTimeout(() => {
this.setState({
status: ENTERED
})
}, this.props.timeout)
// in 为 false 状态是进入后,则要改成离开中
} else{
this.setState({
status: EXITING
})
setTimeout(() => {
this.setState({
status: EXITED
})
}, this.props.timeout)
}
}
优化的完整源码
import React from 'react';
const ENTERING = 'entering'
const ENTERED = 'entered'
const EXITING = 'exiting'
const EXITED = 'exited'
class Transition extends React.Component {
constructor(props) {
super(props);
this.state = {
status: props.in ? ENTERED : EXITED
};
}
componentDidUpdate() {
const { status } = this.state
const { in: nextIn } = this.props
console.log(this.props)
if (nextIn) {
// 优化,进入后和进入中就没必要改状态了
if (status !== ENTERED && status !== ENTERING) {
this.updateStatus(ENTERING)
}
} else {
if (status !== EXITED && status !== EXITING) {
this.updateStatus(EXITING)
}
}
}
updateStatus(status) {
if (status == ENTERING) {
this.performEnter()
} else if (status == EXITING) {
this.performExit()
}
}
performEnter = () => {
const { timeout } = this.props
this.setState({
status: ENTERING
}, () => {
this.onTransitionEnd(timeout, () => this.setState({ status: ENTERED }))
})
}
performExit = () => {
const { timeout } = this.props
this.setState({
status: EXITING
}, () => {
this.onTransitionEnd(timeout, () => this.setState({ status: EXITED }))
})
}
onTransitionEnd = (timeout, callback) => {
setTimeout(callback, timeout)
}
render() {
const { children } = this.props
const { status } = this.state
return (
children(status)
)
}
}
export { Transition }
还有三种组件,下期说