[解決済み] ref コールバックの前に呼び出された componentDidMount
質問
問題点
反応する
ref
をインライン関数定義を使って設定しています。
render = () => {
return (
<div className="drawer" ref={drawer => this.drawerRef = drawer}>
であれば
componentDidMount
では DOM 参照が設定されていません。
componentDidMount = () => {
// this.drawerRef is not defined
私の理解では
ref
コールバックはマウント時に実行されるべきだと理解しています。
console.log
ステートメントを追加すると
componentDidMount
とは
の前に
を呼び出します。
私が見た他のコードサンプルは、例えば
この議論
を見ると、同じような前提で書かれています。
componentDidMount
と呼ばれるべきです。
の後に
任意の
ref
で定義されたコールバックは
render
であれば、それはさらに
の会話で述べられている
つまり、componentDidMountは、すべてのrefコールバックが実行された後に起動されるのですね。 実行されるのですね?
はい、そうです。
私が使っているのはreact 15.4.1
他に試したこと
を確認するために
ref
関数が呼び出されていることを確認するために、クラス上で次のように定義してみました。
setDrawerRef = (drawer) => {
this.drawerRef = drawer;
}
であれば
render
<div className="drawer" ref={this.setDrawerRef}>
この場合、コンソールのロギングにより、コールバックが実際に呼び出されていることがわかります。
の後に
componentDidMount
どのように解決するのですか?
簡単な答えです。
React は、ref が
componentDidMount
または
componentDidUpdate
のフックを使用します。ただし、子プロセスに対してのみ
実際にレンダリングされた
.
componentDidMount() {
// can use any refs here
}
componentDidUpdate() {
// can use any refs here
}
render() {
// as long as those refs were rendered!
return <div ref={/* ... */} />;
}
これは、「Reactは常に
をすべて
を設定する」という意味ではありません。
では、いくつかの例を見てみましょう。
が実行されない例を見てみましょう。
が設定される例を見てみましょう。
レンダリングされなかった要素に参照は設定されない
React は実際にレンダリングされた要素に対してのみ ref コールバックを呼び出します。 レンダリングから返された .
つまり、もしあなたのコードが以下のようなものであれば
render() {
if (this.state.isLoading) {
return <h1>Loading</h1>;
}
return <div ref={this._setRef} />;
}
で、最初は
this.state.isLoading
は
true
であれば
ではない
期待する
this._setRef
が呼び出される前に
componentDidMount
.
これは、最初のレンダリングで
<h1>Loading</h1>
を返した場合、React が他の条件下で、ref を添付する必要がある他の何かを返すことを知る方法はありません。また
refを設定するものがない。
その
<div>
要素が作成されなかったのは
render()
メソッドがレンダリングしてはいけないと言ったからです。
ですから、この例では
componentDidMount
だけが発火します。しかし
の場合は
this.state.loading
に変化すると
false
と表示されます。
this._setRef
が最初に付き、次に
componentDidUpdate
が発射されます。
他の部品に注意する
以下のことに注意してください。 を持つ子供を他のコンポーネントに渡すと、そのコンポーネントは の場合、他のコンポーネントがレンダリングを妨げる(そして問題を引き起こす)何かを行っている可能性があります。
たとえば、これです。
<MyPanel>
<div ref={this.setRef} />
</MyPanel>
は、もし
MyPanel
が
props.children
を出力に含めませんでした。
function MyPanel(props) {
// ignore props.children
return <h1>Oops, no refs for you today!</h1>;
}
繰り返しになりますが、バグではありません。 が作成されていないため、Reactがrefを設定することはできません。 .
ネストされた
ReactDOM.render()
前のセクションと同様に、refを持つ子を他のコンポーネントに渡すと、そのコンポーネントが何かをしてrefを時間内にアタッチできない可能性があります。
例えば、多分それは、子プロセスを
render()
を返さず、代わりに
ReactDOM.render()
をライフサイクルフックで呼び出しています。この例として
の例です。
. その例では、レンダリングしています。
<MyModal>
<div ref={this.setRef} />
</MyModal>
しかし
MyModal
は
ReactDOM.render()
での呼び出し
その
componentDidUpdate
のライフサイクルメソッドです。
componentDidUpdate() {
ReactDOM.render(this.props.children, this.targetEl);
}
render() {
return null;
}
React 16以降、このような のトップレベル レンダリング呼び出しは、ツリー全体に対してライフサイクルが実行されるまで遅延されます。 . これは、時間内に添付された refs が表示されない理由を説明するものです。
この問題の解決策は
ポータル
の代わりに、ネストされた
ReactDOM.render
を呼び出します。
render() {
return ReactDOM.createPortal(this.props.children, this.targetEl);
}
このように
<div>
はレンダリング出力に含まれます。
したがって、この問題が発生した場合は、コンポーネントと参照との間に、子供のレンダリングを遅らせる可能性のあるものがないことを確認する必要があります。
を使用しないでください。
setState
を使用しないでください。
を使用していないことを確認してください。
setState
を使用して、ref コールバックに ref を格納していないことを確認してください。これは、非同期で "終了" する前だからです。
componentDidMount
が先に実行されます。
まだ問題がありますか?
上記のヒントがどれも役に立たない場合、React に問題を報告してください。
関連
-
[解決済み] アップロード前に画像をプレビューする
-
[解決済み] コールバック内で正しい `this` にアクセスする方法
-
[解決済み] レンダリング後に入力フィールドにフォーカスを設定するには?
-
[解決済み】関数の前のエクスクラメーションマークは何をするのですか?
-
[解決済み】ReactJS - "setState "が呼ばれるたびにrenderが呼び出されるのですか?
-
[解決済み] React js 親コンポーネントから子コンポーネントの状態を変更する
-
[解決済み] CORS OriginヘッダーとCSRFトークンによるCSRF保護
-
[解決済み] JSXとLoadshを使用して、ある要素をn回繰り返す方法
-
[解決済み] javascript includes() 大文字小文字を区別しない
-
[解決済み] Javascript の parseInt() で先頭のゼロを削除する。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] <Enter>でjQuery UIダイアログを送信する
-
[解決済み] node.jsで文字列のsha1ハッシュを取得するにはどうすればよいですか?
-
[解決済み] 兄弟ノードを選択する方法はありますか?
-
[解決済み] JavaScriptで:hoverのCSSプロパティを変更する
-
[解決済み] JavaScriptのtoString()関数をオーバーライドして、デバッグ用に意味のある出力を提供することは可能でしょうか?
-
[解決済み] Javascript 空の配列の削減
-
[解決済み] jQueryの$という記号の意味は何ですか?
-
[解決済み] AngularJS - ngRepeatフィルタリングされた結果の参照を取得する方法
-
[解決済み] JavaScriptとLuaの微妙な違い [終了しました]
-
[解決済み] javascriptのキャンバスで画像をリサイズする (スムーズ)