没有React-Router的页面转换

Coc*_*oco 8 css animation react-transition-group

这应该是如此简单,但我已经打破了这几天.我正在尝试动画我的页面过渡.问题是文件SUCK.我一遍又一遍地跟着他们,尝试了各种方式,但无法让它发挥作用.

我想要做的是向右或向左优雅地滑动我的页面,并淡化在其后面优雅地卸载的那个页面.简单吧?我没有在我的网页上使用React Router.

我为此尝试了各种解决方案,但问题似乎在于卸载.更换页面后,现有页面可以在转换之前卸载.我正在使用react-transition-group发布我的尝试,尽管在这一点上,我会接受任何其他有效的解决方案.我不确定react-transition-group是否在实际上得到积极维护,因为还有很多其他帖子可以帮助我做出0回复.

所以在我的app容器上我想要这样的东西:

<App>
  <PageSlider>
     <Page key={uniqueId} />  <==this will be "swapped" through (Redux) props
  </PageSlider>
Run Code Online (Sandbox Code Playgroud)

所以,根据我的阅读,我必须使用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>

    );
  }
}
Run Code Online (Sandbox Code Playgroud)

我还读过我需要做一个"童工厂"来启用现有的东西.我无法在文档中找到这样的例子.由于页面将来自不同的方向,我将向我传递我想要滑动页面的方向,这将告诉页面它获得了什么类.

现在,至于页面本身,我已经将它包装在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?
  }
}
Run Code Online (Sandbox Code Playgroud)

只是为了完成样式将在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, 0);
  transform: translate3d(100%, 0, 0);
}

//to this
.page-right-enter-active {
  -webkit-transform: translate3d(0, 0, 0);
  transform: translate3d(0, 0, 0);
}

 //exiting go from this
    .page-right-exit {
      opacity: 1;
    }
   //to this
    .page-right-exit-active {
      opacity: 0;
    }
Run Code Online (Sandbox Code Playgroud)

所有这些组件都将通过Redux连接,以便他们知道何时触发了新页面以及调用了哪个方向.

有人PLEEEEASE可以帮助我吗?我真的花了几天时间在那里尝试了每个图书馆.我并不喜欢反应过渡组!任何在卸载时工作的库我都会尝试.为什么这不容易?

Coc*_*oco 4

好的。好吧,我在这个问题上挣扎了太久了。我最终放弃了react-transition-group,转而采用纯CSS。这是我的解决方案。

页面滑块.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', component: BlankPage, className: 'placeholder'},
       },
       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;
Run Code Online (Sandbox Code Playgroud)

过渡.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}
}
Run Code Online (Sandbox Code Playgroud)

传入下一个组件,这是我的 React Page 组件,调用方式如下:

应用程序.js

 <div id="app">
      <PageSlider page={this.state.nextRoute} fromDir={this.state.fromDir}/>
   </div>
Run Code Online (Sandbox Code Playgroud)