この質問はこれのフォローアップです:
React Router v4 と MatchWithFade の問題
MatchWithFade
React 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;
これを読み込んでコンソールを開く場合は、One
とTwo
リンクを切り替えます。UI でクロス フェードが発生し、One から Two への移行が完了すると、コンソールに「ONE UNMOUNTING」と表示されます。そうです。
Two One
ここで、 と の間をクリックしますTwo Two
。この場合、Two One
をクリックすると、すぐにコンソールに「TwoTwo がアンマウントされます」と表示されますが、これは問題ありません。ただし、 をクリックTwo Two
すると、約 1 秒後に「TwoTwo がアンマウントされます」と表示されます。これは、親MatchWithFade
が実行するのにかかる時間です。
だから私はここで何が起こっているのか分かりません。私のコードは壊れたのですか?RRv4 がサポートできないことをしていますか? バグを発見しましたか?
ヘルプ/ガイダンスをいただければ幸いです。