Javascript 在React中处理动画和视图层次
我对React有些失望,因为视图层次结构正在破坏我的动画 我有一个组件,用于设置选项卡导航布局,其子项放置在布局的内容部分中。它是一个纯组件,具有title、setTab和currentTab的道具 如果我从视图层次结构和单向数据流的角度来考虑这个问题,我会让布局成为每个视图的子视图,这样视图就可以设置标题、当前选项卡,并且setTab可以委托给其父视图 这基本上就是我正在做的:Javascript 在React中处理动画和视图层次,javascript,animation,reactjs,Javascript,Animation,Reactjs,我对React有些失望,因为视图层次结构正在破坏我的动画 我有一个组件,用于设置选项卡导航布局,其子项放置在布局的内容部分中。它是一个纯组件,具有title、setTab和currentTab的道具 如果我从视图层次结构和单向数据流的角度来考虑这个问题,我会让布局成为每个视图的子视图,这样视图就可以设置标题、当前选项卡,并且setTab可以委托给其父视图 这基本上就是我正在做的: var A = React.createClass({ propTypes: { setTab: Rea
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.addons.cstransitiongroup中的一个按钮来设置版面标题的动画,但我认为问题是相同的:
这里的问题似乎是每次都会完全重新渲染组件,因为渲染树的根已确定。我找到了一些可行的方法,但我不确定这是否是一个最佳实践,所以在我得出结论这就是答案之前,我非常感谢一些反馈 我提出了缝合的概念,作为通过组件层次结构缝合函数的一种方式。这将允许我从子组件设置父组件的状态
function stitch() {
return {
to: (f) => {
this.func = f
},
from: () => {
this.func.apply(null, arguments)
}
}
}
现在我的眼睛看起来像这样:
var Layout = React.createClass({
propTypes: {
currentTab: React.PropTypes.string.isRequired,
onTab: React.PropTypes.func.isRequired,
stitchTitle: React.PropTypes.string.isRequired
},
getInitialState: function() {
return {
title: ''
}
},
componentWillMount: function() {
this.props.stitchTitle((title) => {
this.setState({title})
})
},
// ...
}
var A = React.createClass({
propTypes: {
setTitle: React.PropTypes.func.isRequired
},
componentWillMount: function() {
this.props.setTitle('Page A')
},
//...
}
视图如下所示:
var Layout = React.createClass({
propTypes: {
currentTab: React.PropTypes.string.isRequired,
onTab: React.PropTypes.func.isRequired,
stitchTitle: React.PropTypes.string.isRequired
},
getInitialState: function() {
return {
title: ''
}
},
componentWillMount: function() {
this.props.stitchTitle((title) => {
this.setState({title})
})
},
// ...
}
var A = React.createClass({
propTypes: {
setTitle: React.PropTypes.func.isRequired
},
componentWillMount: function() {
this.props.setTitle('Page A')
},
//...
}
我们所要做的就是把它们缝合在一起
var App = React.createClass({
getInitialState: function() {
return {
currentTab: 'A'
}
},
setTab: function(name) {
this.setState({currentTab:name})
},
componentWillMount: function() {
this.titleStitch = stitch()
},
render: function() {
var view = false
if (this.state.currentTab == 'A') {
view = <A setTitle={this.titleStitch.from}/>
} else {
view = <B setTitle={this.titleStitch.from}/>
}
return (
<Layout currentTab={this.state.currentTab} onTab={this.setTab} stitchTitle={this.titleStitch.to}>
{view}
</Layout>
)
}
});
果然是这样!以下是JSFIDLE:
var App = React.createClass({
getInitialState: function() {
return {
currentTab: 'A'
}
},
setTab: function(name) {
this.setState({currentTab:name})
},
componentWillMount: function() {
this.titleStitch = stitch()
},
render: function() {
var view = false
if (this.state.currentTab == 'A') {
view = <A setTitle={this.titleStitch.from}/>
} else {
view = <B setTitle={this.titleStitch.from}/>
}
return (
<Layout currentTab={this.state.currentTab} onTab={this.setTab} stitchTitle={this.titleStitch.to}>
{view}
</Layout>
)
}
});