React Transition Group - 如何在更新时触发组件的动画?
React Transition Group - How to trigger animation for a component when it updates?
我似乎对 React Transition Group 的工作原理缺乏基本的了解。在这个简单的示例中,我希望组件在每次更新时淡入。它不是。为什么会这样?如果我切换 in prop for ,那么它确实有效。
import React from 'react';
import ReactDOM from 'react-dom';
import { Container, Button, Alert } from 'react-bootstrap';
import { CSSTransition } from 'react-transition-group';
import './styles.css';
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
rerender: false,
};
this.toggle = this.toggle.bind(this);
}
toggle() {
this.setState((state) => ({
rerender: !state.rerender,
}));
}
componentDidMount() {
console.log('Mounted');
}
componentDidUpdate() {
console.log('Updated');
}
render() {
return (
<div>
<Button onClick={this.toggle}>Click</Button>
<CSSTransition
classNames="fade"
in = {true}
timeout={1000}
>
{this.state.rerender ? <p> Render On </p> : <p>Render Off</p>}
</CSSTransition>
</div>
);
}
}
ReactDOM.render(
<Example />,
document.getElementById('root')
);
这是CSS
.fade-enter {
opacity: 1;
}
.fade-enter-active {
opacity: 0;
transition-property: opacity;
transition-duration: 1000ms;
}
.fade-enter-done {
opacity: 0;
}
根据我的路线阅读,我认为将“in”属性保留为始终为真,将始终在每次组件更新时应用 enter-* CSS 类。正如您所看到的,当我按下按钮时,组件就会更新。没有动画发生:
https://codesandbox.io/s/beautiful-brahmagupta-6nmze?file=/index.js
另一方面,如果我用 true 和 false 切换 in prop,那么输入 类 将被应用。在代码沙箱中尝试一下,亲眼看看。
...
<CSSTransition
classNames="fade"
in = {this.state.rerender}
timeout={1000}
>
...
据我所知,React Transition Groups 只在过渡阶段起作用,所以 in prop 应该是
false
到 true
true
到 false
你在源码里可以看的很清楚
_proto.componentDidUpdate = function componentDidUpdate(prevProps) {
var nextStatus = null;
if (prevProps !== this.props) {
var status = this.state.status;
if (this.props.in) {
if (status !== ENTERING && status !== ENTERED) {
nextStatus = ENTERING;
}
} else {
if (status === ENTERING || status === ENTERED) {
nextStatus = EXITING;
}
}
}
this.updateStatus(false, nextStatus);
};
_proto.updateStatus = function updateStatus(mounting, nextStatus) {
if (mounting === void 0) {
mounting = false;
}
if (nextStatus !== null) {
// nextStatus will always be ENTERING or EXITING.
this.cancelNextCallback();
if (nextStatus === ENTERING) {
this.performEnter(mounting);
} else {
this.performExit();
}
} else if (this.props.unmountOnExit && this.state.status === EXITED) {
this.setState({
status: UNMOUNTED
});
}
};
所以如果 props 没有改变什么都不会发生。
在您的情况下,您正在尝试仅应用 enter-* 类:您可以让 in = {this.state.rerender}
并提供 enter -* 类 in css file without exit-*
您还可以使用另一个库在安装时为组件设置动画,例如:React-animations
我似乎对 React Transition Group 的工作原理缺乏基本的了解。在这个简单的示例中,我希望组件在每次更新时淡入。它不是。为什么会这样?如果我切换 in prop for ,那么它确实有效。
import React from 'react';
import ReactDOM from 'react-dom';
import { Container, Button, Alert } from 'react-bootstrap';
import { CSSTransition } from 'react-transition-group';
import './styles.css';
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
rerender: false,
};
this.toggle = this.toggle.bind(this);
}
toggle() {
this.setState((state) => ({
rerender: !state.rerender,
}));
}
componentDidMount() {
console.log('Mounted');
}
componentDidUpdate() {
console.log('Updated');
}
render() {
return (
<div>
<Button onClick={this.toggle}>Click</Button>
<CSSTransition
classNames="fade"
in = {true}
timeout={1000}
>
{this.state.rerender ? <p> Render On </p> : <p>Render Off</p>}
</CSSTransition>
</div>
);
}
}
ReactDOM.render(
<Example />,
document.getElementById('root')
);
这是CSS
.fade-enter {
opacity: 1;
}
.fade-enter-active {
opacity: 0;
transition-property: opacity;
transition-duration: 1000ms;
}
.fade-enter-done {
opacity: 0;
}
根据我的路线阅读,我认为将“in”属性保留为始终为真,将始终在每次组件更新时应用 enter-* CSS 类。正如您所看到的,当我按下按钮时,组件就会更新。没有动画发生: https://codesandbox.io/s/beautiful-brahmagupta-6nmze?file=/index.js 另一方面,如果我用 true 和 false 切换 in prop,那么输入 类 将被应用。在代码沙箱中尝试一下,亲眼看看。
...
<CSSTransition
classNames="fade"
in = {this.state.rerender}
timeout={1000}
>
...
据我所知,React Transition Groups 只在过渡阶段起作用,所以 in prop 应该是
false
到true
true
到false
你在源码里可以看的很清楚
_proto.componentDidUpdate = function componentDidUpdate(prevProps) {
var nextStatus = null;
if (prevProps !== this.props) {
var status = this.state.status;
if (this.props.in) {
if (status !== ENTERING && status !== ENTERED) {
nextStatus = ENTERING;
}
} else {
if (status === ENTERING || status === ENTERED) {
nextStatus = EXITING;
}
}
}
this.updateStatus(false, nextStatus);
};
_proto.updateStatus = function updateStatus(mounting, nextStatus) {
if (mounting === void 0) {
mounting = false;
}
if (nextStatus !== null) {
// nextStatus will always be ENTERING or EXITING.
this.cancelNextCallback();
if (nextStatus === ENTERING) {
this.performEnter(mounting);
} else {
this.performExit();
}
} else if (this.props.unmountOnExit && this.state.status === EXITED) {
this.setState({
status: UNMOUNTED
});
}
};
所以如果 props 没有改变什么都不会发生。
在您的情况下,您正在尝试仅应用 enter-* 类:您可以让 in = {this.state.rerender}
并提供 enter -* 类 in css file without exit-*
您还可以使用另一个库在安装时为组件设置动画,例如:React-animations