0

この質問はこれのフォローアップです:

React Router v4 と MatchWithFade の問題

MatchWithFadeReact Router v4 の使用について、別の (ばかげている可能性がある) 質問があります。私がやりたいのは、ネストされたルートを持つことです。そのため、トップレベルのコンポーネントには次のようなものがあります。

<MatchWithFade pattern='/one' component={One} />

...そして、Oneこれがあるかもしれません:

<Match pattern='/one/one' Component={OneOne} />

これは私には珍しいパターンではありません (そうかもしれませんが)。いずれにせよ、私が観察している動作は、上記の例を使用すると、ロードOneOneするとマウントされ、componentWillUnmountすぐに呼び出されるということです。推測するとTransitionMotion、 の (おそらく非表示の) インスタンスを追跡しOneOne、移行が完了すると、その非表示のコンポーネントがアンマウントされます。基本的な UI に関する限り、OneOneレンダリングされます。ただし、componentWillUnmount何らかのクリーンアップ (たとえば、Redux から何かを削除するなど) を行うと、もちろんそのアクションが実行され、関連付けられているデータはすべてOneOne吹き飛ばされます。

問題を示す完全な例を次に示します。

import React, { Component } from 'react';
import BrowserRouter from 'react-router/BrowserRouter'

import { TransitionMotion, spring } from 'react-motion'
import Match from 'react-router/Match'
import Link from 'react-router/Link';

const styles = {
  fill: { position: 'absolute', top: 0, left: 0 }
};

const MatchWithFade = ({ component:Component, ...rest }) => {
  const willLeave = () => ({ zIndex: 1, opacity: spring(0) })

  return (
    <Match {...rest} children={({ matched, ...props }) => {
      return (
        <TransitionMotion
          willLeave={willLeave}
          styles={matched ? [ {
            key: props.location.pathname,
            style: { opacity: 1 },
            data: props
          } ] : []}
        >
          {interpolatedStyles => {
            return (
              <div>
                {interpolatedStyles.map(config => (
                  <div
                    key={config.key}
                    style={{...styles.fill, ...config.style }}>
                    <Component {...config.data}/>
                  </div>
                ))}
              </div>
            )
          }}
        </TransitionMotion>
      )
    }}/>
  )
}

const TwoOne = () => {
  return (
    <div>Two One</div>
  )
}


class TwoTwo extends Component {
  componentWillUnmount() {
    console.log("TwoTwo will unmount")
  }

  render () {
    return (
      <div>Two Two</div>
    )
  }
}


const TwoHome = () => {
  return (
    <div>Two Home</div>
  )
}


class One extends Component {
  componentWillUnmount () {
    console.log("ONE UNMOUNTING")
  }
  render () {
    return (
      <div style={{ width: 300, border: '1px solid black', backgroundColor: 'orange', minHeight: 200}}>
        One one one one one one one one one one<br />
        One one one one one one one one one one<br />
      </div>
    )
  }
}

const Two = () => {
  return (
    <div style={{ width: 300, border: '1px solid black', backgroundColor: 'yellow', minHeight: 200}}>
      <Match pattern='/two/one' component={TwoOne} />
      <Match pattern='/two/two' component={TwoTwo} />
      <Match pattern='/two(/)?' exactly={true} component={TwoHome} />
    </div>
  )
}


class App extends Component {

  render () {
    return (
        <BrowserRouter>
          <div style={{padding: 12}}>
            <div style={{marginBottom: 12}}>
              <Link to='/one'>One</Link> || <Link to='/two'>Two</Link>
              || <Link to='/two/one'>Two One</Link>
              || <Link to='/two/two'>Two Two</Link>
            </div>
            <div style={{position: 'relative'}}>
              <MatchWithFade pattern='/one' component={One} />
              <MatchWithFade pattern='/two' component={Two} />
            </div>
          </div>
        </BrowserRouter>
    )
  }
}

export default App;

これを読み込んでコンソールを開く場合は、OneTwoリンクを切り替えます。UI でクロス フェードが発生し、One から Two への移行が完了すると、コンソールに「ONE UNMOUNTING」と表示されます。そうです。

Two Oneここで、 と の間をクリックしますTwo Two。この場合、Two Oneをクリックすると、すぐにコンソールに「TwoTwo がアンマウントされます」と表示されますが、これは問題ありません。ただし、 をクリックTwo Twoすると、約 1 秒後に「TwoTwo がアンマウントされます」と表示されます。これは、親MatchWithFadeが実行するのにかかる時間です。

だから私はここで何が起こっているのか分かりません。私のコードは壊れたのですか?RRv4 がサポートできないことをしていますか? バグを発見しましたか?

ヘルプ/ガイダンスをいただければ幸いです。

4

1 に答える 1