新しいReact Context APIは再レンダリングを誘発するか?
質問
新しいReact Context APIを理解しようとして、それを使って遊んでいました。Provider へのデータが更新されたときに、すべてが再レンダリングされるのは何かという、単純なケースを確認したかったのです。
では、私の例では
App
コンポーネントがあり、次のような状態になっています。
this.state = {
number - A random number
text - A static text
}
ここから新しいReact Contextを作成し、その中に
number
と
text
の2つの Consumers に値を渡します。
Number
と
Text
.
私の仮定では、乱数が更新されると、コンテキストが変更され、両方のコンポーネントが再レンダリングを開始するはずです。
しかし、実際には、値は更新されていますが、再レンダリングは起こっていません。
そこで、私の質問ですが
-
コンテキストへの更新は、通常のレンダリングでは伝わらないのでしょうか?コンテキストが変更されたときに、私のログ/色の変更を見ることができないので。
-
そのProviderへのコンシューマはすべて更新されているのか、いないのか?
どのように解決するのですか?
<ブロッククオートコンテキストの更新は、通常のリレンダリングでは反映されないのでしょうか?私はコンテキストが変更されたときに私のログ/色の変化を見ることができないように。
コンテキスト値の更新は、プロバイダーのすべての子プロバイダーに対して再レンダリングをトリガーするのではなく、Consumer 内からレンダリングされるコンポーネントに対してのみ行われます。したがって、このケースでは、Number コンポーネントは Consumer を含んでいますが、Number コンポーネントは再レンダリングされず、むしろ Consumer 内のレンダー関数だけで、その結果、コンテキスト更新で値が変更されるのです。この方法では、すべての子コンポーネントの再レンダリングが発生しないため、非常に高いパフォーマンスを発揮します。
そのプロバイダに対するすべてのコンシューマは更新されますか、されませんか?
そのプロバイダに対するすべてのコンシューマは更新サイクルを経ますが、再レンダリングするかどうかは、reactの仮想DOM比較によって決定されます。このデモは、以下のコンソールで見ることができます。 サンドボックス
EDIT
コンポーネントはContextProviderコンポーネントの子としてレンダリングされ、インラインでレンダリングしてContextProviderの状態を更新するのではなく、ハンドラを渡していることを確認する必要があります。
ContextProvider
パフォーマンス的な使用法
App.js
constructor() {
super();
this.state = {
number: Math.random() * 100,
text: "testing context api"
updateNumber: this.updateNumber,
};
}
render() {
return (
<AppContext.Provider
value={this.state}
>
{this.props.children}
</AppContext.Provider>
);
}
index.js
class Data extends React.Component {
render() {
return (
<div>
<h1>Welcome to React</h1>
<Number />
<Text />
<TestComp />
<AppContext.Consumer>
{({ updateNumber }) => (
<button onClick={updateNumber}>Change Number </button>
)}
</AppContext.Consumer>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(
<App>
<Data />
</App>,
rootElement
);
パフォーマンスの低い使い方
App.js
class App extends Component {
constructor() {
super();
this.state = {
number: Math.random() * 100,
text: "testing context api"
};
}
updateNumber = () => {
const randomNumber = Math.random() * 100;
this.setState({ number: randomNumber });
};
render() {
return (
<AppContext.Provider value={this.state}>
<div>
<h1>Welcome to React</h1>
<Number />
<Text />
<TestComp />
<button onClick={this.updateNumber}>Change Number </button>
</div>
</AppContext.Provider>
);
}
}
関連
-
[解決済み] setStateを呼び出さずにReactコンポーネントを強制的に再レンダリングすることは可能ですか?
-
[解決済み】ReactJS - "setState "が呼ばれるたびにrenderが呼び出されるのですか?
-
[解決済み] Google maps API V3 - 同一地点に複数のマーカーを設置する。
-
[解決済み] Chart.jsを使ってドーナツチャートの中にテキストを追加するには?
-
[解決済み] Reactコンポーネントでthis.setStateを複数回使用するとどうなりますか?
-
[解決済み] Javascript 空の配列の削減
-
[解決済み] Chromeのwebkitインスペクタで「Unsafe JavaScript attempt to access frame with URL...」というエラーが継続的に発生する。
-
[解決済み] Prototypeを使ってtextareaを自動サイズ調整するには?
-
[解決済み] JavaScriptデータフォーマット/プリティプリンタ
-
[解決済み] render関数の外側でReact Contextにアクセスする
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] ジェスト あるクラスの特定のメソッドをモックする方法
-
[解決済み] JavaScriptを使用してHTML要素に属性を追加/更新するには?
-
[解決済み] Reactコンポーネントでthis.setStateを複数回使用するとどうなりますか?
-
[解決済み] JavaScriptのtoString()関数をオーバーライドして、デバッグ用に意味のある出力を提供することは可能でしょうか?
-
[解決済み] javascript includes() 大文字小文字を区別しない
-
[解決済み] jqueryはjavascriptのライブラリなのかフレームワークなのか?[クローズド]
-
[解決済み] AJAX Mailchimp サインアップフォームの統合
-
[解決済み] JavaScriptで長い配列を小さい配列に分割する方法
-
[解決済み] jQueryを使用して、すべてのクリックイベントハンドラを削除するにはどうすればよいですか?
-
[解決済み] <ng-content>が空かどうかを確認する方法は?(これまでのAngular 2+で)