これは、Reactで繰り返し発生する問題です。 componentDidMount
メソッドは、コンポーネントが初めてレンダリングされるときに起動されることが保証されているため、高さやオフセットなどのDOM測定を行うのに自然な場所のようです。ただし、コンポーネントのライフサイクルのこの時点で、間違ったスタイルの読み取り値を何度も受け取ります。コンポーネントは、DOM内で、デバッガーで中断したときですが、まだ画面に描画されていません。ほとんどの場合、幅/高さが100%に設定されている要素でこの問題が発生します。 componentDidUpdate
で測定を行うと、すべて正常に機能しますが、このメソッドはコンポーネントの最初のレンダリングで起動しません。
だから私の質問は-正確にいつcomponentDidMount
が発火するのかは、すべてのブラウザのペイントが完了した後に明らかに発火しないためです。
EDIT:このStackoverflowの問題 は同じテーマを扱います:
また、 このgithubの会話 は何が起こるかを説明しています
反応コンポーネントツリー内では、すべての子コンポーネントもマウントされた後にcomponentDidMount()
が起動されます。つまり、コンポーネントのcomponentDidMount()
は、親がマウントされる前に起動されます。
したがって、DOMの位置やサイズなどを測定する場合、子コンポーネントのcomponentDidMount()
を使用することは、これを行うのに安全な場所/時間ではありません。
あなたの場合:100%の幅/高さのコンポーネントから正確な読み取り値を取得するには、そのような測定を行う安全な場所はtopのcomponentDidMount()
の中にあるでしょう。 反応成分。
100%は、親/コンテナに対する幅/高さです。そのため、測定は親がマウントされた後にのみ行うことができます。
ご存知かもしれませんが、componentDidMount
は最初のレンダリングの直後に一度だけトリガーされます。
測定を行っているので、コンポーネントが更新されたときに測定値が変更された場合に、componentDidUpdate
のときに測定をトリガーすることもできます。
componentDidUpdate
は最初のレンダリングでは発生しないため、測定処理をトリガーするには両方のライフサイクルイベントが必要になる可能性があることに注意してください。この2番目のイベントがトリガーされるかどうか、および異なる測定値があるかどうかを確認します。
私の意見では、可能であればsetTimeout
またはrequestAnimationFrame
の使用を避けるべきです。
コンポーネントがマウントされたときに一度だけ呼び出されます。 APIからデータを取得する非同期リクエストを行うのに最適なタイミングです。フェッチされたデータは内部コンポーネントの状態で保存され、render()ライフサイクルメソッドで表示されます。
シンプル:レンダリング関数の後に実行
DOMにマウントされているものに応答する場合、最も信頼できる方法は refコールバック を使用することです。例えば:
render() {
return (
<div
ref={(el) => {
if (el) {
// el is the <div> in the DOM. Do your calculations here!
}
}}
></div>
);
}
componentDidMount()
を使用してrequestAnimationFrame()
のロジックを遅延させることができます。ロジックshouldは次のペイントの後に発生します。
ただし、ノードが描画されていない理由を確認するには、コードについて詳しく知る必要があります。私はその問題に遭遇したことはありません。 componentDidMount()
は、domノードがページに追加された直後に起動しますが、必ずしもペイントされた後ではありません。