[解決済み] React: 親コンポーネントは状態変化時に変化していない子コンポーネントもすべて再レンダリングする
質問
明確な答えが見つからないのですが、重複していないでしょうか?
私はシンプルなチャットアプリのためにReact + Reduxを使用しています。このアプリは、InputBar、MessageList、および Container コンポーネントで構成されています。コンテナーは (ご想像のとおり) 他の 2 つのコンポーネントをラップして、ストアに接続されています。自分のメッセージの状態と、現在のメッセージ(ユーザーが現在入力しているメッセージ)は、Reduxのストアに保持されています。簡略化した構造です。
class ContainerComponent extends Component {
...
render() {
return (
<div id="message-container">
<MessageList
messages={this.props.messages}
/>
<InputBar
currentMessage={this.props.currentMessage}
updateMessage={this.props.updateMessage}
onSubmit={this.props.addMessage}
/>
</div>
);
}
}
私が抱えている問題は、現在のメッセージを更新するときに発生します。現在のメッセージを更新すると、ストアを更新するアクションがトリガーされ、コンテナを通過してInputBarコンポーネントに戻るプロップが更新されます。
これは動作しますが、副作用として、これが起こるたびに MessageList コンポーネントが再レンダリングされます。MessageList は現在のメッセージを受け取らないので、更新する理由がありません。MessageList が大きくなると、現在のメッセージが更新されるたびにアプリの速度が著しく低下するため、これは大きな問題です。
私はInputBarコンポーネント内で直接現在のメッセージの状態を設定および更新しようとしました(したがって、Reduxアーキテクチャを完全に無視します)、そしてそれは問題を修正しました。
私の質問は
-
親コンポーネントが更新された場合、Reactは常にそのコンポーネント内のすべての直接の子を更新するのでしょうか?
-
ここでは、どのようなアプローチが正しいのでしょうか?
どのように解決するのですか?
<ブロッククオート親コンポーネントが更新された場合、Reactはそのコンポーネント内のすべての直接の子を必ず更新しますか?
いいえ、Reactは以下の場合にのみコンポーネントを再レンダリングします。
shouldComponentUpdate()
が返す
true
. デフォルトでは、このメソッドは常に
true
を返し、新規参入者の微妙なバグを回避します (そして William B が指摘したように、何かが変更されない限り DOM は実際に更新されないので、影響が少なくなります)。
サブコンポーネントが不必要に再レンダリングされないようにするために、サブコンポーネントに
shouldComponentUpdate
メソッドを実装し、そのメソッドが返すのは
true
を返すようにします。もし
this.props.messages
が常に同じ配列であれば、このように単純なものになります。
shouldComponentUpdate(nextProps) {
return (this.props.messages !== nextProps.messages);
}
また、深い比較やメッセージIDの比較などを行いたい場合もあるでしょう、それはあなたの要件に依存します。
編集部:数年後、多くの人が機能的なコンポーネントを使用しています。もしあなたがそうであるなら、次のものをチェックアウトしたいと思うでしょう。
React.memo
. デフォルトでは、機能コンポーネントは、クラスコンポーネントのデフォルトの動作と同様に、毎回再レンダリングされます。この挙動を変更するには
React.memo()
を使用し、オプションで
areEqual()
関数を提供します。
関連
-
[解決済み】Reactでclsxを使用する方法
-
[解決済み] react - createMuiThemeとcreateThemeの違い。
-
[解決済み] jest: テストスイートの実行に失敗しました。予期しないトークンのインポート
-
[解決済み] MUI Boxは何のためのコンポーネントですか?
-
[解決済み] React TypeScriptで作業しているときに、Jestが予期しないトークンに遭遇した
-
[解決済み] ReactJS - SCRIPT1010: 期待される識別子 - IE11 で本番ビルドが実行されない
-
[解決済み] Reduxの非同期フローになぜミドルウェアが必要なのか?
-
[解決済み】React-ReduxとmapStateToProps()を理解する。)
-
[解決済み】React Formでpropsが変更されたときに状態を更新する
-
[解決済み] reduxの接続コンポーネントは、どのように再レンダリングするタイミングを知ることができますか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】ReactJS: マテリアルuiのブレークポイントについて
-
[解決済み] Apolloクライアントでログアウトした後、ストアをリセットする
-
[解決済み] FontAwesomeの無料パッケージに含まれているアイコンのオブジェクト名はどこにあるのですか?
-
[解決済み] ReactJS: Warning: setState(...): 既存の状態遷移の間に更新することはできません
-
[解決済み] sh: react-scripts: npm start の実行後にコマンドが見つからない。
-
[解決済み] React TypeScriptで作業しているときに、Jestが予期しないトークンに遭遇した
-
[解決済み] ReactJS - SCRIPT1010: 期待される識別子 - IE11 で本番ビルドが実行されない
-
[解決済み] react.jsで複数のモジュールをエクスポートする
-
[解決済み] ReactJs "インバリアント違反..." リアクトの古典的な問題
-
[解決済み] Reactのrender()にFont Awesomeのアイコンを入れる方法