入門」シリーズ最終回は、メモ化の応用例のご紹介です。メモ化したコールバック関数を、条件によって無効にします。ゲームが終わったらonClickハンドラは無効にするsrc/components/GameContext.jsモジュールでマス目のクリックイベントに定められたコールバック(handleClick())は、勝ちが決まったらゲームの処理を先に進めないようにしました。ハンドラ関数そのものは、クリックするたびに呼び出されます。xIsNext]);};今回のお題は、ゲームが終わったらハンドラのコールバックをなくしてしまうということです。ゲーム終了をマス目のコンポーネントに伝えるため、コンテクストのモジュールsrc/components/GameContext.jsは、終了のフラグ(finished)をvalueプロパティに加えます。(<GameContext.Providervalue={{finished,}}></GameContext.Provider>);};マス目のコンポーネントモジュールsrc/components/Square.jsはonClickイベントハンドラに、ゲーム終了フラグ(finished)で判別するつぎのような式を与えればよいでしょう。これで、ゲームが決着したらハンドラのコールバック関数そのものが呼ばれなくなります。onClick(id)}></button>);};対応するコンテクストモジュールsrc/components/GameContext.jsの修正はつぎのとおりです。ゲームが決着したらコールバックは呼ばれないのですから、終了フラグ(finished)の判定は要らなくなります。他方で、9マスすべてが埋まったら、これもゲーム終了としなければなりません。[history]);};コンテクストのモジュールsrc/components/GameContext.jsは、これででき上がりです。つぎのコード001に記述全体をまとめましょう。マス目のonClickハンドラをメモ化するマス目のコンポーネントモジュールsrc/components/Square.jsは、onClickハンドラに条件演算子の式を与えました。コールバックはやはりメモ化しておきたいところです。onClick(id)}></button>);};上記ハンドラの式をそのままuseCallbackフックに渡すとつぎのようになります。onClick(id)}onClick={handleClick}></button>);};一応動きはするものの、適切ではありません。つぎのような警告が示されます。返される値のひとつnullは関数ではなく、useCallbackが依存を正しく確かめられないからです。フックの第1引数には関数を渡さなければなりません。useMemoフックでコールバック関数をメモ化する値をメモ化するのはuseMemoフックでした。値には関数も含まれます。useMemoでコールバック関数をメモ化することもできるのです。useCallbackをuseMemoで書き替えれば、つぎのような構文になります(「useCallback」参照)。[依存配列]);もっとも、このような回りくどい書き方をする必要は普通ありません。そのためのuseCallbackフックです。今回のように関数でない値(null)を含めたいときは、useMemoフックが使えます。マス目のコンポーネントモジュールsrc/components/Square.jsには、onClickイベントのコールバック関数をつぎのように定めればよいでしょう。onClick]);};これで、onClickイベントのコールバック関数はメモ化され、ゲームの決着がついたらハンドラは無効(null)になって呼び出されません。書き直したマス目のコンポーネントモジュールsrc/components/Square.jsの記述全体は、つぎのコード002にまとめたとおりです。