我想知道是否有人可以提供一些有关如何使用React.js实现动画组件/页面切换的见解。
我想要实现的是组件/页面转换,例如http://www.semplicelabs.com/上的转换 - 转换不透明度和margin-top的标头以及转换不透明度的内容。
当显示新的组件/页面时,当前显示的组件/页面应该转换为之前新组件/页面转换。到目前为止,我所拥有的是LayoutComponent
将页面组件呈现为CSSTransitionGroup
:
import React from 'react/addons';
export default class LayoutComponent extends React.Component {
constructor(props) {
super(props);
this.state = { page: '' };
},
setPage(page) {
this.setState({ page });
}
render() {
return (
<React.addons.CSSTransitionGroup transitionName='page'>
{this.state.page}
</React.addons.CSSTransitionGroup>
);
}
}
我还有两个页面组件,FirstPage
和SecondPage
。
import React from 'react';
export default class FirstPage extends React.Component {
render() {
return (
<div>
<header className='header'>
<div className='container'>
First Header
</div>
</header>
<div className='content'>
<div className='container'>
First Content
</div>
</div>
</div>
);
}
}
SecondPage
代码和FirstPage
代码之间的唯一区别是.container
div和类名称中的内容。
我接下来尝试做的是添加.8s
持续时间的离开转换以及.8s
持续时间和延迟的输入转换。我看到的主要问题是新页面组件在旧页面的离开转换完成之前安装。这是我目前的CSS:
.page-enter {
background-color: #f2f2f2;
transition: background-color .8s linear .8s;
}
.page-enter-active {
background-color: #f2f1f1;
}
.page-leave {
background-color: #f2f1f1;
transition: background-color .8s linear;
}
.page-leave-active {
background-color: #f2f2f2;
}
.page-enter .header {
margin-top: -80px;
opacity: 0;
transition: opacity .8s ease-in-out .8s;
transition: margin-top .8s ease-in-out .8s;
}
.page-enter-active .header {
margin-top: 0;
opacity: 1;
}
.page-leave .header {
margin-top: 0;
opacity: 1;
transition: opacity .8s ease-in-out;
transition: margin-top .8s ease-in-out;
}
.page-leave-active .header {
margin-top: -80px;
opacity: 0;
}
.page-enter .content {
opacity: 0;
transition: opacity .8s ease-in-out .8s;
}
.page-enter-active .content {
opacity: 1;
}
.page-leave .content {
opacity: 1;
transition: opacity .8s ease-in-out;
}
.page-leave-active .content {
opacity: 0;
}
我知道我可以使用transitionAppear={true}
设置初始安装的动画 - 但这对于在旧组件转出之前安装新组件的问题没有帮助。
这是我已经困难了几天的问题,我无法找到解决方案。
一些代码可以解决: https://jsfiddle.net/gonsfx/xva2g6oo/
答案 0 :(得分:1)
我已经在页面中添加了一个状态来保存opacity
(用于动画)并在组件以小延迟安装时将其设置为1(initial = 0)。所以我为每个页面添加了两个函数。
componentDidMount() {
setTimeout(() => {
this.setState({
opacity: 1
});
}, 20);
}
getStyle() {
return { opacity: this.state.opacity };
}
然后我添加了一个构造函数来制作初始的东西......
constructor(props) {
super(props);
this.state = { opacity: 0 };
this.getStyle = this.getStyle.bind(this);
this.componentDidMount = this.componentDidMount.bind(this);
}
Here是一个DEMO。
组件会立即显示在页面上,所以我认为不可能制作淡出动画(至少,我没有找到解决方案)。
答案 1 :(得分:0)
行。在浏览了许多最新的和过时的文档后,我设法解决了这个问题。 Here is the solution
基本上,react-router只关注父容器的动画。但这意味着使用ReactTransitionGroup
,我们可以在退出组件中挂钩componentWillLeave
方法,在那里我们可以让个别孩子操纵。儿童组件也可以ReactCSSTransitionGroup
运动,以促进appear
过渡。
因此,您可能无法仅使用CSSTransitionGroup
,而是CSSTransitionGroup
和TransitionGroup
的混合。
因此,更改页面会自动通过钩子为子项设置动画,而进入页面时会使用CSSTransitionGroup
进行单个动画。
解决方案中的setTimeout
可能看起来像黑客,但这是我现在所能做的全部。