Reactのドキュメントが、componentWillMountではなく、componentDidMountでAJAXを実行することを推奨するのはなぜですか?


102

タイトルはそれをすべて言います。なぜcomponentDidMountDOMアクセスが必要なものに適しているのか理解していますが、AJAXリクエストは必ずしもまたは通常は必要ありません。

何ができますか?


@FurkanO彼はコンポーネントによってレンダリングされたDOM要素へのアクセスを意味したと思います。そして、彼が完全に正しいのはcomponentWillMount、コンポーネントをマウントしなかった場合、その要素にアクセスしようとすると失敗するからです。
ZekeDroid、2016

@AlanH。私の質問を削除しました。もちろん、componentDidMountのdomにアクセスできます。これはルールであり、それについて説明することは何もありません。ありがとう。
FurkanO 2016

私の意見では、componentDidMountの後にAjax関数を呼び出すのは、最初にElementがスムーズにレンダリングされることを最初に確認する必要があるためです。その後、ajax呼び出しを実行できます。最初にajaxを呼び出して何かエラーが発生すると、レンダリングで問題が発生します
Faris Rayhan

回答:


62

componentDidMount副作用のためです。イベントリスナーの追加、AJAX、DOMの変更など

componentWillMountめったに役に立ちません。特にサーバー側のレンダリングに注意する場合(イベントリスナーを追加すると、エラーやリークが発生し、その他の多くの問題が発生する可能性があります)。

componentWillMountコンストラクタと同じ目的を果たすため、クラスコンポーネントからの削除についての話があります。createClassコンポーネントに残ります。


1
イベントリスナーを追加すると、サーバー上で常にエラーが発生し、リークが発生しcomponentWillMountます。区別はあまりわかりません。
アランH.

18
@Alan-クライアントサイドとサーバーサイドの両方でReactを使用している場合、内部のすべてcomponentWillMountがサーバーサイドレンダーで実行されることがわかります。Wherasを使用している場合はcomponentDidMount、クライアント側でのみ実行されます。結果として、componentWillMount外部の相互作用を実行したり、イベントなどにバインドしたりすることは、素晴らしいアイデアではありません。サーバーサイドでコンポーネントをレンダリングする計画がない場合でも、コードの移植性を高めるだけの理由ではありません。これは、@ daniulaの回答で説明されている主な理由の外にあります。
マイクドライバー

3
componentWillMountはサーバーで実行されますが、componentWillUnmount(リスナーを削除する場所)は実行されません。これにより、リスナーが追加され、クリーンアップされなくなります。
ブリガンド14年

Reactコアチームの人々は、componentWillMountを将来のバージョンから削除することを検討しています。
チェンバレン

1
@AnkitSinghaniyaはサーバーのレンダリングと浅いユニットテストを壊します。
ブリガンド2017

36

私も最初は同じ問題を抱えていました。でお願いしてみることにしましたcomponentWillMountが、結局色んな小さな問題になってしまいます。

ajax呼び出しが新しいデータで終了したときにレンダリングをトリガーしていました。ある時点で、コンポーネントのレンダリングにサーバーからの応答を取得するよりも時間がかかりました。この時点で、ajaxコールバックが、マウントされていないコンポーネントでレンダリングをトリガーしていました。これは一種のエッジケースですが、おそらくもっと多いので、に固執する方が安全componentDidMountです。


わかりました、ありがとう。それはそのようなものかもしれませんが、あなたが正しいと思いますが、レンダーが完了する前にajaxリクエストが完了する可能性があるのは驚くべきことです。
アランH.

1
@daniulaよろしいですか?レンダリングの前にAJAXリクエストをどのように終了できますか?
Leon Grapenthin

4
これはブラウザの非同期の世界です。1つの関数が常に残りの関数よりも高速であると想定することはできません。私が述べたように、それはエッジケースであり、おそらくレンダリングプロセスを最適化する必要があることを意味しますが、適切なライフサイクルメソッドを使用することで、この時点での生活がはるかに容易になります。
daniula

1
@SooChengKoh ES6クラスコンストラクターはと同等であるため、ajax呼び出しにcomponentWillMountは引き続き使用する必要がありcomponentDidMountます。
daniula 2016

1
@SooChengKoh-設定する必要のある状態、つまりクライアントとサーバーの競合状態につながるようなコンストラクターでは絶対に何もすべきではありません。setStateコンポーネントコンストラクターを呼び出さないでください。AJAX呼び出しがいつ完了するかを判断する方法がありません。twitter.com/dan_abramov/status/576453138598723585
チェンバレン

3

ドキュメントによると、状態をに設定してcomponentWillMountも、再レンダリングはトリガーされません。AJAX呼び出しがブロックされておらずPromise、成功時にコンポーネントの状態を更新するを返す場合、コンポーネントがレンダリングされると応答が到着する可能性があります。componentWillMountあなたが要求したデータを用いてレンダリングコンポーネントされている、あなたが期待する動作を持っていません。再レンダリングトリガーされません。

フラックスライブラリのいずれかを使用し、要求されたデータが最終的にストアに格納される場合、コンポーネントは接続されています(または接続されたコンポーネントから継承します)。そのデータの受信はおそらくプロップを変更するため、これは問題になりません。最終的に。


1
componentWillMount最初のレンダリングの前に新しい状態が定義されているからといって、再レンダリングはトリガーされません。ただしsetState、AJAXコールバックで呼び出された場合、最初のレンダリングの後に確実に呼び出され、再レンダリングがトリガーされます。
webdif 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.