[解決済み] ReactのuseCallback/useMemoは何をするのですか?
質問
で述べたように
ドキュメント
,
useCallback
メモ化されたコールバックを返す。
インラインコールバックと入力の配列を渡します。
useCallback
は、入力のいずれかが変更された場合にのみ変更される、コールバックのメモ化されたバージョンを返します。これは、不要なレンダリングを防ぐために参照の等価性に依存する最適化された子コンポーネントにコールバックを渡すときに便利です (例: shouldComponentUpdate)。
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
しかし、Reactではどのように動作し、どこで使うのがベストなのでしょうか?
追伸:私は コードペンの例 で視覚化すると、より理解しやすくなると思います。 ドキュメントで説明 .
どのように解決するのですか?
不要な再描画を防ぎ、パフォーマンスを向上させたい場合に使用します。
から取得した子コンポーネントにコールバックを渡す 2 つの方法を比較してみましょう。 React Docs :
1. レンダリングにおける矢印機能
class Foo extends Component {
handleClick() {
console.log('Click happened');
}
render() {
return <Button onClick={() => this.handleClick()}>Click Me</Button>;
}
}
2. コンストラクタでのバインド(ES2015)
class Foo extends Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log('Click happened');
}
render() {
return <Button onClick={this.handleClick}>Click Me</Button>;
}
}
仮定の話
<Button>
が実装されているとすると
PureComponent
として実装された場合、最初の方法では
<Button>
が再レンダリングするたびに
<Foo>
で新しい関数が作成されるため、再レンダリングが行われます。
render()
の呼び出しごとに新しい関数が作られるからです。二つ目の方法では
handleClick
メソッドが一度だけ作成され
<Foo>
のコンストラクタで一度だけ作成され、レンダリング中に再利用されます。
両方のアプローチをフックを使用する機能的なコンポーネントに変換すると、これらは等価です (一種の)。
1. レンダーでの矢印関数 -> 非メモ化コールバック
function Foo() {
const handleClick = () => {
console.log('Click happened');
}
return <Button onClick={handleClick}>Click Me</Button>;
}
2. コンストラクタでのバインド (ES2015) -> メモ化されたコールバック
function Foo() {
const memoizedHandleClick = useCallback(
() => console.log('Click happened'), [],
); // Tells React to memoize regardless of arguments.
return <Button onClick={memoizedHandleClick}>Click Me</Button>;
}
最初の方法では、機能コンポーネントを呼び出すたびにコールバックが作成されますが、2番目の方法では、Reactがコールバック関数をメモしてくれるので、コールバックが複数回作成されることはありません。
したがって、最初のケースで
Button
を使って実装した場合
React.memo
を使用すると、常に再レンダリングされます(何らかのカスタム比較関数がある場合を除く)。
onClick
prop は毎回異なるため、(何らかのカスタム比較関数がない限り) 再レンダリングされます。
ほとんどの場合、最初の方法で問題ありません。Reactのドキュメントにも書いてある通りです。
レンダーメソッドでarrow関数を使用しても良いですか?一般的には コールバック関数にパラメータを渡す最も簡単な方法であることがよくあります。 コールバック関数にパラメータを渡す最も簡単な方法です。
パフォーマンスの問題がある場合は、ぜひとも最適化してください。
関連
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] JavaScriptでオブジェクトをディープクローンする最も効率的な方法は何ですか?
-
[解決済み] なぜGoogleはJSONレスポンスにwhile(1);を前置するのでしょうか?
-
[解決済み] とは何ですか! (not not)演算子とは何ですか?
-
[解決済み] callとapplyの違いは何ですか?
-
[解決済み] Reactルータを使ったプログラムによるナビゲーション
-
[解決済み] React JSX内のループ
-
[解決済み] javascript:void(0)」とは何ですか?
-
[解決済み] Reactのこの3つの点は何をするところなのでしょうか?
-
[解決済み】JavaScript版sleep()とは?)
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] チェックボックスが選択されているかどうかを確認するjQuery
-
[解決済み] 文字列がすべて同じ部分文字列で構成されているかどうかを調べるにはどうすればよいですか?
-
[解決済み] オブジェクトの配列からReactコンポーネントをレンダリングする
-
[解決済み] JavaScriptで文字列を数値に変換する最速の方法は何ですか?
-
[解決済み] サブドメインにまたがってlocalStorageを使用する
-
[解決済み] ECMAScriptとは?
-
[解決済み] jQueryで入力ファイルが空かどうかをチェックする方法
-
[解決済み] Promise : then vs then + catch [重複].
-
[解決済み] Prototypeを使ってtextareaを自動サイズ調整するには?
-
[解決済み] JavaScriptデータフォーマット/プリティプリンタ