React.memo/forwardRef を HoC と呼ぶのは適切か?
TL:DR;
memo はそう呼んで良い。forwardRef は HoC とは呼ばない方が無難。
---
コンポーネント #設計 パターンとしての HoC( Higher-order Component )はほぼ滅んだが(少なくとも新規にそう書くべきケースはあまりない)、 #React でコンポーネントを渡してコンポーネントをつくるという考えそのものは滅んでないように見える。 たとえば React.memo や React.forwardRef がそうで、いや forwardRef は引数の形式が特殊だが、これらは第一引数にコンポーネント定義を渡してコンポーネントを作っている。
code:typescript
export default React.memo(function MyComponent(props) {
return (...)
}, () => { ... })
code:typescript
export default React.forwardRef(function MyComponent(props, ref) {
return (...)
})
これらのトップレベル API は現時点で hooks に代替されておらず、今のところされる見通しもない( useMemo はユースケースは似ているが「代替 API」といえるほど同じではない )。
すると、これらは「現代まで代替されず生き残った HoC の例だ」、と言えるだろうか。
しかし、通常 HoC の例としてこれらを上げていることはない。React 公式ドキュメントもそのようには説明しないだろう。
facebook/react のコードベースではどう扱われているか。
forwardRef の第一引数名は render である。そもそも (props, ref) => JSX という形式なのでこれはコンポーネント定義とは言いがたい(ただし中に hooks を書いても動く)。
Issue で forwardRef は HoC じゃないよと主張する人を見かけた(コアチームメンバーではないので公式見解とは言えないが)
一方 React.memo の第一引数は type だ。
エラーメッセージでも The first argument must be a component. と呼んでいる。
React.memo も forwardRef も、いわゆる普通の FC や class component を返す実装にはなっていない。
REACT_MEMO_TYPE や REACT_FORWARD_REF_TYPE という特別扱いされた $$typeof を持つオブジェクトが返される。
この点があまり Higher-order っぽくなくて HoC と呼ぶのをためらわせている。
コンポーネントを受け取ってコンポーネントを返していることには違いないが、少なくとも設計パターンとしての HoC が React.memo に採用されているわけではない。
…と思ったら公式ドキュメントに書いてあった
React.memo は高階コンポーネントです。