反応ルーターの公式ドキュメントのコンポーネント部分で、それは言う:
あなたが使用する場合
component
(の代わりに、render
またはchildren
、下の)ルータの用途はReact.createElement
、新規に作成する要素を反応させるの与えられたコンポーネントから。つまり、component
プロップにインライン関数を提供すると、レンダリングごとに新しいコンポーネントが作成されます。これにより、既存のコンポーネントを更新するだけでなく、既存のコンポーネントがアンマウントされ、新しいコンポーネントがマウントされます。インラインレンダリングにインライン関数を使用するrender
場合は、またはchildren
プロップ(下記)を使用します。
この一節をどうやって理解するのですか?これは小さな例で説明できます。
'react'からReactをインポートします。 ReactDOMを 'react-dom' からインポートします。"react-router-dom" から{BrowserRouter、Route}をインポートします。 クラスBar extends React.Component { componentDidMount(){ console.log( "componentDidMount" ) } render(){ return ( <div> Bar </ div> ) } } クラスApp extends React.Component { constructor(prop){ super (支柱); this .state = {idx:1 } } handleClick =()=>.setState(state =>({idx:state.idx + 1 })) }; render(){ return ( <div> <div> { this .state.idx} <button onClick = { this .handleClick}> add </ button> </ div> <div> <BrowserRouter> <Route component = {Bar } /> </ BrowserRouter> </ div> </ div> ); } } ReactDOM.render( <App />、document。
上記のコードでは、Appコンポーネントに単純なBarコンポーネントがあり、コンポーネント属性を介してRouteによって参照されます。
<Route component = {Bar} />
このとき、ページ上のボタンをクリックすると、BarコンポーネントのcomponentDidMountはトリガーされません。
AppのBarコンポーネントでidxを受け入れる必要があるとしましょう。idxをプロップとしてBarに渡す必要があります。このとき、次のコードを記述できます。
'react'からReactをインポートします。 ReactDOMを 'react-dom' からインポートします。"react-router-dom" から{BrowserRouter、Route}をインポートします。 class Bar extends React.Component { componentDidMount(){ console.log( "componentDidMount" ) } render(){ const {idx} = this .props; return ( <div> in Bar:{idx} </ div> ) } } クラスApp extends React.Component { constructor(prop){ super(prop); この.state = {idx:1 } } handleClick =()=> { this .setState(state =>({idx:state.idx + 1 })) }; render(){ return ( <div> <div> { this .state.idx} <button onClick = { this .handleClick}> add </ button> </ div> <div> <BrowserRouter> <Route component = {( )=>(<Bar idx = { this .state.idx} />)} /> < </ div> ); } } ReactDOM.render( <App />、document.getElementById( 'root'));
ただし、この時点でボタンをクリックすると、上記のドキュメントにあるように、BarのcomponentDidMountが呼び出されていることがわかります。
つまり、コンポーネントプロップにインライン関数を提供すると、レンダリングごとに新しいコンポーネントが作成されます。これにより、既存のコンポーネントを更新するだけでなく、既存のコンポーネントがアンマウントされ、新しいコンポーネントがマウントされます。
したがって、正しい表現は
<Route render = {()=>(<Bar idx = { this .state.idx} />)} />
現時点では、Barコンポーネントは、アンマウントとマウントを繰り返していません。
その背後にある原理は、reactがコンポーネントの状態を比較してdomノードを更新する方法を決定するとき、最初にコンポーネントのタイプとキーを比較する必要があるということです。使用中<Route component={() => (<Bar idx={this.state.idx}/>)}/>
、呼び出しのためReact.createElement
、コンポーネントのタイプはBarではなく、無名関数です。Appコンポーネントは、レンダリングされるたびに新しい無名関数を生成するため、生成されるコンポーネントのタイプは常に異なるため、アンマウントとマウントが繰り返されます。
リファレンスドキュメント:
https : //reactjs.org/docs/reconciliation.html
https://reactjs.org/docs/react-api.html#createelement
著者:グレート神はレンガを移動するために私をもたらし
ます。https://www.jianshu.com/p/a2a9b469a422リンク
出典:ジェーンの本は
、著者が著作権を保有しています。営利目的の複製については、作者に連絡して承認を得てください。非営利目的の複製については、出典を明記してください。