使用ReactCSSTransitionGroup和React Router可以实现复杂的动画效果吗?

4
我想知道ReactCSSTransitionGroup是否适合我的用例。
在一个路由上,我有一个搜索按钮,当用户点击它时,按钮应该过渡消失,同时加载搜索页面。加载完成后,页面的某些区域将从侧面动画进入。
我正在使用React Router,因此整个页面过渡似乎很简单,但以这种方式动画化特定元素似乎更具挑战性。
ReactCSSTransitionGroup能否处理此任务,还是我需要寻找替代方案?
2个回答

3
我认为答案是“是的,这是可能的”。
我在CodePen上写了一个概念验证。使用ReactCSSTransitionGroup时有一些需要注意的地方,其中之一在Google Groups的这个讨论中提到。在那里,有人说:

你需要保留ReactCSSTransitionGroup并添加/删除其内容。

所以,基本上,如果您有一个将动画应用于其子元素的组件,则需要将子元素包装在ReactCSSTransitionGroup中。以下是基于我的示例的伪代码:
假设您的路由器设置如下:
<Router history={hashHistory}>
  <Route path="/" component={App}>
    <IndexRoute component={Home}/>
    <Route path="/repos" component={Repos}>
      <Route path="/repos/:userName/:repoName" component={Repo}/>
    </Route>
    <Route path="/about" component={About}/>
  </Route>
</Router>

我希望能够对<App>的子组件进行动画效果。以下是可能的效果展示:

function App(props) {
  return (
    <div>
      <h1>App</h1>
      <nav>
        <ul>
          <li><NavLink to="/" onlyActiveOnIndex={true}>Home</NavLink></li>
          <li><NavLink to="/about">About</NavLink></li>
          <li><NavLink to="/repos">Repos</NavLink></li>
        </ul>
      </nav>
      <ReactCSSTransitionGroup>
        {React.cloneElement(props.children, {
          key: getKey(props.location.pathname)
        })}
      </ReactCSSTransitionGroup>
    </div>
  );
}

请注意,您需要将ReactCSSTransitionGroup放在子组件之外。此外,每个元素都需要一个唯一的键,以便ReactCSSTransitionGroup可以跟踪它们。通常,路径名是一个很好的选择。在我的特定用例中,我使用了一个函数来获取路径名的某个前缀,这样在导航库之间时,此级别的转换就不会发生。您会明白我的意思。
我可以在<Repos>组件中做类似的事情:
function Repos(props) {
  return (
    <div>
      <h2>Repos</h2>
      <ul>
        <li><NavLink to="/repos/reactjs/react-router">React Router</NavLink></li>
        <li><NavLink to="/repos/facebook/react">React</NavLink></li>
      </ul>
      <ReactCSSTransitionGroup>
        {props.children ?
          React.cloneElement(props.children, {
            key: props.location.pathname
          }) :
          null}
      </ReactCSSTransitionGroup>
    </div>
  );
}

类似的想法在这里。这一次我使用了完整的路径名,因为在这个级别上,我确实希望在各个仓库之间进行过渡。
我还没有在大型应用程序上尝试过这个方法,所以我会听从更有经验的人的建议。然而,正如我之前所说,这至少应该是可能的。您应该能够组合简单的动画来获得复杂的动画效果。

0

ReactCSSTransitionGroup 实际上是 ReactTransitionGroup 的高级接口。如果你用 <TransitionGroup /> 包装你的子元素,你将会得到额外的生命周期方法,比如 componentWillEnter(callback)componentWillLeave(callback) 等等... 你可以在这些方法中运行动画,然后在动画完成时触发回调函数。我在下面使用了 jQuery 来进行动画,但你也可以使用任何动画库来控制元素。

以下代码演示了这个概念:

<Router history={hashHistory}>
  <Route path="/" component={Parent}>
    <Route path="/child" component={Child}/>
  </Route>
</Router>


var Child = React.createClass({
  componentWillEnter: function(callback) {
    var $this = $(ReactDOM.findDOMNode(this));
    $this.css({ opacity: 0 });
    $this.fadeIn('slow', callback);
  },
  componentWillLeave: function(callback) {
    var $this = $(ReactDOM.findDOMNode(this));
    $this.fadeOut('slow', callback);
  },
  render: function() {
    return (
      <p>This child element will fade in when entering and fade out when leaving.</p>
    )
  }
});

var Parent = React.createClass({
  render: function() {
    return (
      <h1>Parent element</h1>
      <TransitionGroup>
        {this.props.children}
      </TransitionGroup>
    )
  }
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接