我构建了一个以价格为道具的组件,并将之前的价格保存为状态。我使用getDerivedStateFromProps(newProps,oldState)来计算新价格是增加还是减少。如果增加,我想用绿色背景闪烁旧价格和新价格之间的差异,如果价格下降,我想用红色背景闪烁差异。我想显示闪光灯和当前价格,一秒钟左右后闪光灯消失,并保持当前价格。
为此,我使用以下react组件和CSS过渡。
反应成分:
import React from 'react';
import './PriceTicker.css';
class PriceTicker extends React.Component {
constructor(props) {
super(props)
this.state = { price: undefined, arrow: undefined }
}
static getDerivedStateFromProps(newProps, oldState) {
if (newProps.price && oldState.price && newProps.price !== oldState.price) {
const upArrow = '\u21E7'
const downArrow = '\u21E9'
const change = (newProps.price-oldState.price).toFixed(2)
if (newProps.price > oldState.price) {
return { price: newProps.price, arrow: upArrow, bgColor: 'green', change}
}
else {
return { price: newProps.price, arrow: downArrow, bgColor: 'red', change }
}
}
return { price: newProps.price, arrow: undefined, tickClass: undefined, change:undefined}
}
render(props) {
return (
<div>
{this.state.arrow &&
<span className='fadeout' style={{
backgroundColor: this.state.bgColor,
}}>{this.state.arrow} {this.state.change}</span>
}
{this.state.price? ' '+this.state.price : 'waiting for first price...'}
</div>
);
}
}
css:
@keyframes fadeout{
0%{opacity:1;visibility:visible;}
99%{opacity:0;}
100%{opacity:0;visibility: hidden;}
}
.fadeout {
animation-name:fadeout;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
}
它有效,但仅在第一个价格上升或下降时有效。随后的价格变化不会消失,而是直到下一次变化之前,闪光灯仍然可见。我怀疑这是因为我正在使用css类来处理动画,并且过渡仅触发一次。
我的示例存储库为here。 (git克隆,纱线安装,纱线运行)
可以看到{@ 3}}的视频,该视频显示了第一个价格变动的代码,但随后的变动仍然可见。
每次重绘我的react组件时,如何重置与css类相关联的css转换?
编辑:
要变通解决此问题,我最终只使用componentDidUpdate内部的setTimeout()来触发将CSS类切换回非动画状态的回调。工作代码已推送到上述存储库中。
componentDidUpdate(prevProps, prevState, snapshot){
if(this.state.tickClass === 'fadeout'){
setTimeout(()=>this.setState({tickClass:'waiting'}),2000/**fade duration**/)
}
}
如果css提供了在动画完成后切换类的功能,那就好了,例如animation-on-complete-class':xxx。这将提供比animation-fill-mode属性更多的常规功能。