Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/475.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在React中处理动画和视图层次_Javascript_Animation_Reactjs - Fatal编程技术网

Javascript 在React中处理动画和视图层次

Javascript 在React中处理动画和视图层次,javascript,animation,reactjs,Javascript,Animation,Reactjs,我对React有些失望,因为视图层次结构正在破坏我的动画 我有一个组件,用于设置选项卡导航布局,其子项放置在布局的内容部分中。它是一个纯组件,具有title、setTab和currentTab的道具 如果我从视图层次结构和单向数据流的角度来考虑这个问题,我会让布局成为每个视图的子视图,这样视图就可以设置标题、当前选项卡,并且setTab可以委托给其父视图 这基本上就是我正在做的: var A = React.createClass({ propTypes: { setTab: Rea

我对React有些失望,因为视图层次结构正在破坏我的动画

我有一个组件,用于设置选项卡导航布局,其子项放置在布局的内容部分中。它是一个纯组件,具有title、setTab和currentTab的道具

如果我从视图层次结构和单向数据流的角度来考虑这个问题,我会让布局成为每个视图的子视图,这样视图就可以设置标题、当前选项卡,并且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.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>  
    )
  }
});