这应该是如此简单,但我已经打破了这几天.我正在尝试动画我的页面过渡.问题是文件SUCK.我一遍又一遍地跟着他们,尝试了各种方式,但无法让它发挥作用.
我想要做的是向右或向左优雅地滑动我的页面,并淡化正在其后面优雅地卸载的页面.简单吧?我没有在我的网页上使用React Router.
我为此尝试了各种解决方案,但问题似乎在于卸载.更换页面后,现有页面可以在转换之前卸载.我正在使用react-transition-group发布我的尝试,尽管在这一点上,我会接受任何其他有效的解决方案.我不确定react-transition-group是否在实际上得到积极维护,因为还有很多其他帖子可以帮助我做出0回复.
所以在我的app容器上我想放这样的东西:
- <App>
- <PageSlider>
- <Page key={uniqueId} /> <==this will be "swapped" through (Redux) props
- </PageSlider>
因此,根据我的阅读,我必须使用TransitionGroup容器作为我的PageSlider,以便它可以管理我的页面的进入和退出.所以这里是:
- class PageSlider extends Component {
- constructor(props) {
- super(props);
- }
- render() {
- return (
- <TransitionGroup
- component="div"
- id="page-slider"
- childFactory={child => React.cloneElement(child,{classNames: `page-${this.props.fromDir}`,timeout: 500}
- )}
- >
- {this.props.children}
- </TransitionGroup>
- );
- }
- }
我还读过我需要做一个“童工厂”来启用现有的东西.我无法在文档中找到这样的例子.由于页面将来自不同的方向,我将向我传递我想要滑动页面的方向,这将告诉页面它获得了什么类.
现在,至于页面本身,我已经将它包装在CSSTransition中.关于这一切如何传承的文档中没有很好的例子,所以我真的很困惑这里做什么:
- class Page extends Component {
- constructor(props) {
- super(props);
- }
- render() {
- return (
- <CSSTransition> <==????????
- {this.props.children} Do props get passed down?
- </CSSTransition> Which ones?
- ); Does "in" get taken care of?
- }
- }
只是为了完成样式将在CSS中应用如下:
- .page {
- display: flex;
- flex-direction: column;
- height: 100%;
- position: absolute;
- top: 0;
- bottom: 0;
- -webkit-transition: all 500ms ease-in-out;
- transition: all 500ms ;
- }
- //go from this
- .page-right-enter {
- -webkit-transform: translate3d(100%,0);
- transform: translate3d(100%,0);
- }
- //to this
- .page-right-enter-active {
- -webkit-transform: translate3d(0,0);
- transform: translate3d(0,0);
- }
- //exiting go from this
- .page-right-exit {
- opacity: 1;
- }
- //to this
- .page-right-exit-active {
- opacity: 0;
- }
所有这些组件都将通过Redux连接,以便他们知道何时触发了新页面以及调用了哪个方向.
有人PLEEEEASE可以帮助我吗?我真的花了几天时间在那里尝试了每个图书馆.我并没有结合反应过渡组!任何在卸载时工作的库我都会尝试.为什么这不容易?
解决方法
好.好吧,我为WAAAAY挣扎太久了.我终于抛弃了react-transition-group,并且转向纯CSS.这是我的解决方案.
PageSlider.js
- import React,{ Component } from 'react';
- import PropTypes from 'prop-types';
- require('./transitions.scss');
- const BlankPage = (props) => <div className="placeholder"></div>;
- class PageSlider extends Component {
- constructor(props) {
- super(props);
- this.state = {
- nextRoute: props.page,pages: {
- A: {key: 'A',component: BlankPage,className: 'placeholder'},B: {key: 'B',},currentPage: 'A'
- };
- }
- componentDidMount() {
- //start initial animation of incoming
- let B = {key: 'b',component: this.state.nextRoute,className: 'slideFromRight'}; //new one
- let A = Object.assign({},this.state.pages.A,{className: 'slideOutLeft'}); //exiting
- this.setState({pages: {A: A,B: B},currentPage: 'B'});
- }
- componentWillReceiveProps(nextProps) {
- if (nextProps.page != this.state.nextRoute) {
- this.transition(nextProps.page,nextProps.fromDir);
- }
- }
- transition = (Page,fromDir) => {
- if (this.state.nextRoute != Page) {
- let leavingClass,enteringClass;
- let pages = Object.assign({},this.state.pages);
- const current = this.state.currentPage;
- const next = (current == 'A' ? 'B' : 'A');
- if (fromDir == "right") {
- enteringClass = 'slideFromRight';
- leavingClass = 'slideOutLeft';
- } else {
- enteringClass = 'slideFromLeft';
- leavingClass = 'slideOutRight';
- }
- pages[next] = {key: 'unique',component: Page,className: enteringClass};
- pages[current].className = leavingClass;
- this.setState({pages: pages,nextRoute: Page,currentPage: next});
- }
- }
- render() {
- return (
- <div id="container" style={{
- position: 'relative',minHeight: '100vh',overflow: 'hidden'
- }}>
- {React.createElement('div',{key: 'A',className: this.state.pages.A.className},<this.state.pages.A.component />)}
- {React.createElement('div',{key: 'B',className: this.state.pages.B.className},<this.state.pages.B.component />)}
- </div>
- );
- }
- }
- PageSlider.propTypes = {
- page: PropTypes.func.isrequired,fromDir: PropTypes.string.isrequired
- };
- export default PageSlider;
transition.scss
- .placeholder {
- position: absolute;
- left: 0;
- width: 100vw;
- height: 100vh;
- background: transparent;
- -webkit-animation: slideoutleft 0.5s forwards;
- -webkit-animation-delay: 10;
- animation: slideoutleft 0.5s forwards;
- animation-delay: 10;
- }
- .slideFromLeft {
- position: absolute;
- left: -100vw;
- width: 100vw;
- height: 100vh;
- -webkit-animation: slidein 0.5s forwards;
- -webkit-animation-delay: 10;
- animation: slidein 0.5s forwards;
- animation-delay: 10;
- }
- .slideFromRight {
- position: absolute;
- left: 100vw;
- width: 100vw;
- height: 100vh;
- -webkit-animation: slidein 0.5s forwards;
- -webkit-animation-delay: 10;
- animation: slidein 0.5s forwards;
- animation-delay: 10;;
- }
- .slideOutLeft {
- position: absolute;
- left: 0;
- width: 100vw;
- height: 100vh;
- -webkit-animation: slideoutleft 0.5s forwards;
- -webkit-animation-delay: 10;
- animation: slideoutleft 0.5s forwards;
- animation-delay: 10;
- }
- .slideOutRight {
- position: absolute;
- left: 0;
- width: 100vw;
- height: 100vh;
- -webkit-animation: slideoutright 0.5s forwards;
- -webkit-animation-delay: 10;
- animation: slideoutright 0.5s forwards;
- animation-delay: 10;
- }
- @-webkit-keyframes slidein {
- 100% { left: 0; }
- }
- @keyframes slidein {
- 100% { left: 0; }
- }
- @-webkit-keyframes slideoutleft {
- 100% { left: -100vw; opacity: 0 }
- }
- @keyframes slideoutleft {
- 100% { left: -100vw; opacity: 0}
- }
- @-webkit-keyframes slideoutright {
- 100% { left: 100vw; opacity: 0}
- }
- @keyframes slideoutright {
- 100% { left: 100vw; opacity: 0}
- }
app.js
- <div id="app">
- <PageSlider page={this.state.nextRoute} fromDir={this.state.fromDir}/>
- </div>