この質問は、このフォローアップであるリアクト:ネストされたマッチのルートはルータV4とMatchWithFade
Trouble with React Router v4 and MatchWithFade
私はルータV4をMatchWithFade
を使用して反応について別の(潜在的に愚かな)疑問を持っています。私は何をしたいのは、ネストされたルートを持っているので、トップレベルのコンポーネントは、これを持っているかもしれません:
<MatchWithFade pattern='/one' component={One} />
...そしてOne
は、この可能性があります:
<Match pattern='/one/one' Component={OneOne} />
をこれは私を珍しいパターン(私はそれかもしれないが)として打つことはありません。いずれにしても、上記の例を使用して、OneOne
をロードすると、マウントされ、次にcomponentWillUnmount
が直ちに呼び出されます。私が推測するには、TransitionMotion
がOneOne
の(おそらく隠された)インスタンスを追跡しており、移行が完了すると、その隠れたコンポーネントがアンマウントされると言いたいと思います。基本的なUIに関する限り、OneOne
がレンダリングされます。しかし、componentWillUnmount
が(例えば、Reduxから何かを削除しているような)クリーンアップを行った場合、もちろんそのアクションは起動され、OneOne
に関連付けられたデータは吹き飛ばされます。あなたはこれをロードして、コンソール、One
とTwo
リンク間のトグルを開く
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;
場合:
は、ここでの問題を示している完全な例です。 UIでクロスフェードが起こるのを見ると、1から2への移行が完了すると、コンソールに「ONE UNMOUNTING」と表示されます。そうです。
Two One
とTwo Two
の間をクリックします。この場合、Two One
をクリックすると、すぐにコンソールに「TwoTwo unmount」と表示されます。しかし、Two Two
をクリックすると、約2秒後に「TwoTwo unmount」と表示されます。これは、親のMatchWithFade
が実行にかかる時間です。
ここで何が起こっているのか分かりません。私のコードはちょうど破壊されたのですか? RRv4でサポートできないことをやっていますか?私はバグを発見しましたか?
ヘルプ/ガイダンスがありがとうございます。
Ah!面白い! 'MatchWithFade'コードは、React-Routerのドキュメントからそのまま受け継がれていました。そして、私は 'props.location.pathname'と' rest.pattern'の違いを見ています。 'rest.pattern'は現在の' Match'コンポーネントにマッチするパスの一部で、 'props.location.pathname'は完全パスです。これはyesを意味し、キーは変更され、複数のインスタンスがロードされます。これはおそらく、RRドキュメントが 'props.location.pathname'ではなく' rest.pattern'を使うように更新されなければならないことを意味し、他のものはこの問題に遭遇しません。 – hairbo
これはちょっと複雑に思えるかもしれませんが、私が考えているのはこれです:1)各はユニークです。 2つのアニメーションがある場合、それは2つの異なるアニメーションです。 2)要素は、内の各キーに対して作成されます。 docsの例では、新しい場所の ''がレンダリングされるので、 'props.location.pathname'を使うとキーとしてうまく動作します。あなたのコードでは、ただ一つの ''がレンダリングされるので、変更されないキーが必要です。 –
そうです、それは理にかなっています。そして、そうですね、私の頭の中で私の頭を掴むのは少し難しいですが、浸透し始めています。その例では、 'rest.pattern'はprops.location.pathnameと同じようにキーとして機能します。 'そうですか?そして、誰か(ああ、私のような)がそのコードをスワイプして修正し、そのキーを変更する心配がないという点で、もう少しばかげてしまうという追加の利点があります。 – hairbo