考虑一个用例:一个内部带有文本的块(从存储中获取文本)。当文本更改时 - 块顺利消失,另一个块出现。
伪代码以获得更好的说明:
import TransitionGroup from 'react-addons-transition-group'
@connect((state) => ({text: state.text}))
class Container extends React.Component {
render() {
return (
<div>
<TransitionGroup>
<Block key={this.props.text}/> // change block when text changes
</TransitionGroup>
</div>
)
}
}
@TransitionWrapper() // pass componentWillEnter through wrapper
@connect((state) => ({text: state.text}), null, null, {withRef: true})
class Block extends React.Component {
componentWillEnter(callback) {
// fancy animations!!!
const el = ReactDOM.findDOMNode(this);
TweenMax.fromTo(el, 1, {
alpha: 0,
}, {
alpha: 1,
onComplete: callback
});
}
componentWillLeave (callback) {
const el = ReactDOM.findDOMNode(this);
TweenMax.to(el, 1, {
alpha: 0,
onComplete: callback
});
}
render() {
return (
<div>{this.props.text}</div>
)
}
}
当 state.text 改变时会发生什么?
- 新
Block
出现,因为key
变;componentWillEnter
为它启动动画。伟大的。 - 旧块被重新渲染并
componentWillLeave
为其启动动画。 - 当第一个动画完成时,重新渲染再次发生。
问题是第 2 步:旧元素应该与旧数据一起消失,但由于重新渲染,它会将他的内容从 更改为新内容store
,因此用户会看到:
store.text = 'Foo'
. 用户在屏幕上看到一个带有文本“Foo”的块。store.text = 'Bar'
. 用户看到两个块,屏幕上都有文本“栏”。一个街区正在消失。Foo
动画结束,用户在屏幕上看到一个带有文本的块。
我相信现在使用过渡非常普遍,这应该是一个常见的问题,但我很惊讶我找不到任何相关的东西。我能想到的最好的主意是在元素即将离开时“冻结”元素上的道具(或传递 previous store
,因此它会使用以前的数据重新渲染),但这对我来说感觉很糟糕。
解决这个问题的最佳方法是什么?