没有React-Router的页面转换 [英] page transitions without React-Router

查看:64
本文介绍了没有React-Router的页面转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这应该很简单,但是我已经为此烦恼了好几天.我正在尝试为页面过渡设置动画.问题是文档SUCK.我已经一遍又一遍地跟踪他们,并尝试了所有方法,但无法使其正常工作.

This should be so simple, but I've been breaking my head over this for days. I'm trying to animate my page transitions. The problem is the docs SUCK. I've followed them over and over and tried every which way, but can't get it to work.

我想做的是向右或向左滑动我的页面,并淡入淡出正在其后面的页面.简单吧?我的页面没有使用React Router.

What I want to do is slide my pages gracefully either right or left, and fade the one that is unmounting gracefully out behind it. Simple right? I am NOT using React Router for my pages.

我为此尝试了各种解决方案,但问题似乎在解决上.替换页面后,现有页面将被卸载,然后才能过渡出来.我正在发布我的使用react-transition-group的尝试,尽管在这一点上,我将接受其他可行的解决方案.我不确定react-transition-group是否实际上正在得到积极维护,因为还有很多其他帖子提供了0响应的帮助.

I've tried a variety of solutions for this, but the problem seems to be on the unmounting. When the page is replaced, the existing page gets unmounted before it can transition out. I'm posting my attempt with react-transition-group, though at this point, I'll accept any other solution that works. I'm not sure react-transition-group is being actively maintained actually, because there are numerous other postings for help with 0 responses.

因此,在我的应用容器上,我想放置以下内容:

So on my app container I want to put something like this:

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

因此,根据我的阅读,我必须使用TransitionGroup容器作为我的PageSlider,以便它可以管理页面的进入和退出.所以去了:

So, from what I've read, I have to use a TransitionGroup container as my PageSlider for this, so that it will manage the entering and exiting of my page. So here goes:

 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>

    );
  }
}

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

I also read I need to do a "child Factory" to enable the exiting stuff. There was absolutely no example of this I could find in the docs. Since the pages will come from different directions, I will pass to this the direction from which I want to slide the page, which will tell the page what class it gets.

现在,对于页面本身,我已经将其包装在CSSTransition中,就像这样.文档中没有很好的例子说明这一切如何传递,所以我真的很困惑在这里做什么:

Now, as for the page itself, I have wrapped it in a CSSTransition like so. There were no good examples in the docs of how this all gets passed down, so I'm really confused what to do here:

 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中应用,如下所示:

And just to finish the styles will be applied in CSS something like this:

.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;
    }

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

All of these components will be connected through Redux so they know when a new page has been triggered and which direction has been called.

有人可以帮我吗?我实际上已经花了几天时间,尝试了每个图书馆.我不愿意反应组的反应!任何尝试卸载的库我都会尝试.为什么这样不容易?

Can someone PLEEEEASE help me on this? I've literally spent days and tried every library out there. I'm not wedded to react-transition-group! Any library that works on the unmount I'll try. Why is this not easier?

推荐答案

确定.好吧,我为此而苦苦挣扎太久了.我最终转储了react-transition-group,并使用了纯CSS.这是我的解决方法.

OK. Well, I struggled with this for WAAAAY too long. I finally dumped react-transition-group, and went pure CSS. Here's my solution.

PageSlider.js

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', 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;

transition.scss

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}
}

传入下一个组件,这是我的react Page组件,其名称如下:

Passing in the next component, which is my react Page component, called like so:

app.js

 <div id="app">
      <PageSlider page={this.state.nextRoute} fromDir={this.state.fromDir}/>
   </div>

这篇关于没有React-Router的页面转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆