564 文字
3 分

Q. コンポーネントをuseCallbackで作るかスコープ外の関数として切り出すべきか

Github の通知を眺めていると、useCallback を利用してコンポーネントを作っている次のようなコードに対して、コンポーネントとして切り出した方がいいのではないか?とレビューコメントが付いているのを見つけた。

const LargeComponent = () => {
// many hooks
const ConditionalComponent = () => {
// ...
if (value === null) {
return null;
}
return <HogeComponent value={value} />;
};
return (
<div>
<ConditionalComponent />
<button onClick={handleClick}>Click me</button>
</div>
);
};

このコメントを補足する形で、次のような内容のコメントを付けた。

パフォーマンスについて#

多くのケースで、ほぼ差は発生しない。

useCallback は、その仕組み上、比較やキャッシュの参照のオーバヘッドが存在するが、それによって useCallback を利用しない方が良いと言えるような差は基本的に発生しない。

コードの質について#

次のような主張があって然るべきだと思う。

  • 関数やコンポーネントはなるべく純粋であるべき
  • 利用されない可能性があるものは分離すべき
    • 複雑度を下げるように圧力がかかるべき

実際このようにコンポーネント内のコンポーネントが全体的に許容されていくと、ここのコンポーネントに対して網羅的なテストを書くことが難しくなっていく。

また、React コンポーネントとしての一貫性を損なうという主張も考えられる。useCallback内などで他の hooks が呼ばれることは、本来想定されておらずバグの原因になりうるため、避けるべきだ。

将来性について#

以前から React チームなどは、実際にパフォーマンスが問題になるようなケースを除いて、useCallback や useMemo を積極的には利用していないように思われる。

また React Compiler も控えており、問題になっていない/なりそうなければ利用しなくて良いという主張には一定の合理性があるように思う。

一方で、useCallback や useMemo を利用するコストは低いため、積極的に利用して構わないという主張もあって然るべきだ。

Q. コンポーネントをuseCallbackで作るかスコープ外の関数として切り出すべきか
https://blog.ohirunewani.com/posts/q-usecallback-vs-outside-component/
作者
hrdtbs
公開日
2024-08-16
ライセンス
CC BY-NC-SA 4.0