関数コンポーネントが推奨される理由は「短く書けるから」ではない
TL;DR
#React にある程度詳しい人なら知ってるが、初心者が誤解しがちな話。 React 開発チームの(よく見られる)見解として「そもそも関数コンポーネントのほうがメンタルモデルとしてより良い」というのがある
Q. functional components があるってことは dysfunctional(機能不全の) components もあるの?
A. class components って言うんですけど
イベントハンドラはコンポーネントに属するのではなく「1回のレンダリング」に属するべきである
コンポーネントの handleClick() は常に同じものではなく、ある時刻 t における handleClick() と考えるべきである
副作用もまた、コンポーネントに属する「ライフサイクル」ではなく「1回のレンダリング」に属する「レンダリング結果」である
この事実をクラスコンポーネントは自然に記述することができない
クラスコンポーネントにおいて、イベントハンドラはコンポーネントそのものに属する
this.handleClick という書き方の見た目通り( this はコンポーネントのインスタンス )だ
state やイベントハンドラがある時刻 t におけるレンダリング結果に属さないと、時に不自然な挙動が生まれる
たとえば非同期に実行されるメソッドは意図よりも「新しすぎる state」を読んでしまうケースがある
「本当はクリックした時点の state をイベントハンドラに覚えててほしいんだけど!」
So if our component re-renders while the request is in flight, this.props will change. The showMessage method reads the user from the “too new” props.
関数コンポーネントは、その中の state やコールバックが「1回のレンダリングに属する」という事実を自然に記述することができる
これは hooks どうこうは関係なく、クロージャの一般的な性質による
見た目的にも、コンポーネントそれ自体が render() メソッドの役目をし、その中にすべてが記述される形になる
もちろん記述のラクさは重要な性質ではあるが、それがメインではない。
むしろ、性質として優れているから書きやすくなるよう公式が頑張ってる、という理解をしたほうが良い。