2017-08-29 7 views
2

私はリアクションルータv4とリアクショントランジショングループv2を使ってページスライドアニメーションをテストしています。ページリアクションルータv4とリアクショントランジショングループv2

const RouterMap =() => (
    <Router> 
    <Route render={({ location }) => 
     <TransitionGroup> 
     <CSSTransition key={location.pathname.split('/')[1]} timeout={500} classNames="pageSlider" mountOnEnter={true} unmountOnExit={true}> 
      <Switch location={location}> 
      <Route path="/" exact component={ Index } /> 
      <Route path="/comments" component={ Comments } /> 
      <Route path="/opinions" component={ Opinions } /> 
      <Route path="/games" component={ Games } /> 
      </Switch> 
     </CSSTransition> 
     </TransitionGroup> 
    } /> 
    </Router> 
) 

とCSS:

.pageSlider-enter { 
    transform: translate3d(100%, 0, 0); 
} 

.pageSlider-enter.pageSlider-enter-active { 
    transform: translate3d(0, 0, 0); 
    transition: all 600ms; 
} 
.pageSlider-exit { 
    transform: translate3d(0, 0, 0); 
} 

.pageSlider-exit.pageSlider-exit-active { 
    transform: translate3d(-100%, 0, 0); 
    transition: all 600ms; 
} 

アニメーションのように怒鳴るです:ご覧のとおり

enter image description here

detail pageからindex pageスライドはすべての権利(権利であるアニメーション左へ)。しかし、Backアイコンをクリックすると、index pageが左から右に出てくることを願っています。

.pageSlider-enter { 
    transform: translate3d(-100%, 0, 0); 
} 
.pageSlider-exit.pageSlider-exit-active { 
    transform: translate3d(100%, 0, 0); 
    transition: all 600ms; 
} 

しかし、どのように一緒に2つのアニメーションを組み合わせる:

私は怒鳴るようCSSを変更した場合、ページは左から右に出てくるだろう知っていますか?一般に、ユーザーが戻るアイコンをクリックするたびに、アニメーションはfrom left to rightになります。


更新:@MatijaGのため2017年8月31日

おかげで、パスの深さを使用すると、本当にすごいアイデアです。私はそれに続き、新しい問題を抱えていました。

function getPathDepth(location) { 
    let pathArr = (location || {}).pathname.split('/'); 
    pathArr = pathArr.filter(n => n !== ''); 
    return pathArr.length; 
} 

<Route render={({ location }) => 
    <TransitionGroup> 
    <CSSTransition 
     key={location.pathname.split('/')[1]} 
     timeout={500} 
     classNames={ getPathDepth(location) - this.state.prevDepth > 0 ? 'pageSliderLeft' : 'pageSliderRight' } 
     mountOnEnter={true} 
     unmountOnExit={true} 
    > 
     <Switch location={location}> 
     <Route path="/" exact component={ Index } /> 
     <Route path="/comments" component={ Comments } /> 
     <Route path="/opinions" component={ Opinions } /> 
     <Route path="/games/lol" component={ LOL } /> // add a new route 
     <Route path="/games" component={ Games } /> 
     </Switch> 
    </CSSTransition> 
    </TransitionGroup> 
} /> 

とCSS更新:

.pageSliderLeft-enter { 
    transform: translate3d(100%, 0, 0); 
} 
.pageSliderLeft-enter.pageSliderLeft-enter-active { 
    transform: translate3d(0, 0, 0); 
    transition: all 600ms; 
} 
.pageSliderLeft-exit { 
    transform: translate3d(0, 0, 0); 
} 
.pageSliderLeft-exit.pageSliderLeft-exit-active { 
    transform: translate3d(100%, 0, 0); 
    transition: all 600ms; 
} 

.pageSliderRight-enter { 
    transform: translate3d(-100%, 0, 0); 
} 
.pageSliderRight-enter.pageSliderRight-enter-active { 
    transform: translate3d(0, 0, 0); 
    transition: all 600ms; 
} 
.pageSliderRight-exit { 
    transform: translate3d(0, 0, 0); 
} 
.pageSliderRight-exit.pageSliderRight-exit-active { 
    transform: translate3d(-100%, 0, 0); 
    transition: all 600ms; 
} 

アニメーション: '/ゲーム' に '/' から

enter image description here

はokです、と '/ゲーム' からバックへ'/'はまだOKです(タイプ1:ルートA - >ルートB、2ルートのみ)。しかし、最初に「/」から「/ゲーム」、そして「/ゲーム」から「/ゲーム/笑」になると、第2段階でアニメーションが失われます(タイプ2:ルートA→ルートB→ルートC 、3つ以上のルート)。また、 '/ games/lol'から '/ games'に戻って '/'に戻ると、スライドアニメーションはタイプ1と同じではありません。

誰でもこの問題について考えていますか?

+1

私はキー= {場所を使用する理由が何であるかを尋ねるかもしれません。 pathname.split( '/')[1]}これはa-> b-> cの問題だと思います。 これは/ gamesと/ games/lolが同じキーを持っているため、アニメーションがトリガーされないことを意味します(/ =>未定義、/ games =>ゲーム、/ games/lol => games)。あなたはkey = {location.key}を使うべきです – MatijaG

+0

@MatijaG、はい、あなたは正しいです。それは私の間違いです。私はHashRouterのために 'key = {location.pathname.split( '/')[1]}'を使用します。 – jason

+0

@MatijaG、この問題が深刻になると、いくつかの問題があることがわかりました。私は別の質問をしました:https://stackoverflow.com/questions/45978263/dynamic-page-sliding-animation-with-react-router-v4-and-react-transition-group-v。時間があれば、本当に助けてくれることを願っています。とにかく、ありがとう。 – jason

答えて

4

よくある主な問題は、あなたの質問でも、アプリケーションがどの方向を使うべきかを知っているかどうかを指定しなかったことです。

これは、パスの深さと長さを使用することです。ナビゲーションするパスが現在のパスよりも「深い」場合は、右から左に遷移しますが、

もう1つの問題は、ルーターがあなたに行っている場所だけを提供することです。そのため、前の場所(または深さ)を保存して比較できるようにする必要があります。その後

はCSSのクラス名を切り替えるだけの問題で、この線に沿って 何か:

import React from 'common/react' 
import { withRouter, Route, Switch } from 'react-router' 

function getPathDepth (location) { 
    return (location || {}).pathname.split('/').length 
} 
class RouterMap extends React.PureComponent { 
    constructor (props, context) { 
     super(props, context) 
     this.state = { 
      prevDepth: getPathDepth(props.location), 
     } 
    } 

    componentWillReceiveProps() { 
     this.setState({ prevDepth: getPathDepth(this.props.location) }) 
    } 
    render() { 

     return (
      <Router> 
       <Route render={ ({ location }) => 
        (<TransitionGroup> 
         <CSSTransition 
          key={ location.pathname.split('/')[1] } 
          timeout={ 500 } 
          classNames={ getPathDepth(location) - this.state.prevDepth ? 'pageSliderLeft' : 'pageSliderRight' } mountOnEnter={ true } unmountOnExit={ true } 
         > 
          <Switch location={ location }> 
           <Route path='/' exact component={ Index } /> 
           <Route path='/comments' component={ Comments } /> 
           <Route path='/opinions' component={ Opinions } /> 
           <Route path='/games' component={ Games } /> 
          </Switch> 
         </CSSTransition> 
        </TransitionGroup>) 
       } 
       /> 
      </Router> 
     ) 
    } 
} 

export default withRouter(RouterMap) 

Codepen例:https://codepen.io/matijag/pen/ayXpGr?editors=0110

+0

本当にありがとう、パスの深さを使用して本当に素晴らしいアイデアです。私はあなたに続き、新しい問題を抱えています。アニメーションは2つのルート(**ルートA→ルートB **)でのみ機能します。私はこれについて混乱しています。詳細については、質問の説明を更新しました。 – jason