【发布时间】:2015-07-11 04:00:44
【问题描述】:
我对 React 感到有些沮丧,因为视图层次结构破坏了我的动画。
我有一个<Layout> 组件,它设置了一个tab-nav 布局,它的子元素被放置在布局的内容部分中。它是一个纯组件,具有 title、setTab 和 currentTab 的 props。
如果我从视图层次结构和单向数据流的角度考虑这一点,我会将布局设置为每个视图的子视图,以便视图可以设置标题、当前选项卡和 setTab 可以是委托给其父级。
这基本上就是我正在做的事情:
var A = React.createClass({
propTypes: {
setTab: React.PropTypes.func.isRequired
},
render: function() {
return (
<Layout title="A Page" currentTab="A" setTab={this.props.setTab}>
This is A
</Layout>
)
}
});
现在你可以使用 React Router 之类的东西作为标签,但是现在,我只有一个简单的顶级组件切换标签及其状态:
var App = React.createClass({
getInitialState: function() {
return {
currentTab: 'A'
}
},
setTab: function(name) {
this.setState({currentTab:name})
},
render: function() {
var component = false
if (this.state.currentTab == 'A') {
return <A setTab={this.setTab}/>
} else {
return <B setTab={this.setTab}/>
}
}
});
在您想开始添加一些动画之前,这一切都很好。
在我的<Layout> 组件中,我有一个高亮块,我想在标签之间切换时从左到右设置动画。
<div className="tabbar">
<div className={"highlight " + this.props.currentTab}></div>
<div className="tabs">
<div className="tab" onClick={() => {this.props.setTab('A')}}>A</div>
<div className="tab" onClick={() => {this.props.setTab('B')}}>B</div>
</div>
</div>
这是该动画的 CSS:
.highlight {
border-bottom: 3px solid red;
width: 50%;
position: absolute;
top: 0;
bottom: 0;
transition: left .25s ease-in-out;
}
.highlight.A {
left: 0;
}
.highlight.B {
left: 50%;
}
我也在尝试使用 React.addons.CSSTransitionGroup 为布局的标题设置动画,但我认为问题是一样的:
这里的问题似乎是 <Layout> 组件每次都完全重新渲染,因为渲染树的根(<A/> 和 <B/>)正在改变。
所以现在的问题是,我如何反转视图层次结构,以便 <Layout> 不会不断重新渲染,以便动画可以工作?
注意:在一个不太人为的例子中,布局还可以从<A/> 获取其他道具,例如 onClick 处理程序。
这是一个 JSFiddle,展示了我的挫败感:
【问题讨论】:
标签: javascript animation reactjs