我想知道 ReactCSSTransitionGroup 是否适合我的用例。
在一条路线上,我有一个搜索按钮,当用户单击它时,该按钮应该在它加载到搜索页面时转换离开。加载后,页面的某些区域将从侧面动画。
我将它与 React Router 一起使用,因此整个页面转换看起来很简单,但以这种方式为特定元素设置动画似乎更具挑战性。
ReactCSSTransitionGroup 应该能够处理这个问题还是我应该寻找替代方案?
我想知道 ReactCSSTransitionGroup 是否适合我的用例。
在一条路线上,我有一个搜索按钮,当用户单击它时,该按钮应该在它加载到搜索页面时转换离开。加载后,页面的某些区域将从侧面动画。
我将它与 React Router 一起使用,因此整个页面转换看起来很简单,但以这种方式为特定元素设置动画似乎更具挑战性。
ReactCSSTransitionGroup 应该能够处理这个问题还是我应该寻找替代方案?
我认为答案是“是的,这是可能的”。
我在 CodePen 上写了一个概念证明。有一些陷阱,其中一个在 Google Groups 的讨论ReactCSSTransitionGroup
中提到。在那里,有人说:
您需要保留 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>
);
}
类似的想法在这里。这次我使用了完整的路径名,因为在这个级别上,我确实想要在各个 repos 之间进行转换。
我还没有在大型应用程序上尝试过这个,所以我会听从有更多经验的人。但是,正如我之前所说,它至少应该是可能的。您应该能够编写简单的动画来获得复杂的动画。
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>
)
}
});