やったこと
レビューのまとめ
onClick属性に渡す関数をmemo化したかった。
自分は最初、以下のようにコードを記述した。
const onClickTag = useCallback(() => {
~~~~~
},
[]
)
// map内での関数
onClick={() => onClickTag(props.id)}
しかし、これでは毎回アロー関数が生成されてしまい、useCallbackでmemo化した意味がなかった。
そのため、onClick属性には以下のように関数を渡す必要がある。
onClick={onClickTag}
これであれば、memo化の恩恵を受けることができる
ではなぜ、上記の記述をしてしまったのか?
A. それは、引数を持った関数をuseCallbackでmemo化したかったためだ
onClick={onClickTag(props.id)}
こういった記述はそもそもできない。
これは、onClick属性に対して関数を渡す必要があるのに、関数の結果を渡してしまっているからだ
この形式でエラーを起こさないようにするためには、
const handleChange = useCallback((id) => () => {
doStuff(id)
, []}
onClick={handleChange(id)}
上記のようにカリー化をする必要があるが、memo化をすることはできない。
そのため、memo化できるところとそうでないところはしっかり判断していく必要がある
変数の命名について
自分は最初, propsの完了ボタンが押された際に渡す関数の命名に
onClickCompleteButton
という命名をしていた。。
これはこのコンポーネント内部から見ると違和感を感じないかもしれない。
しかし、コンポーネントを使う側からの視点で見ると、CompleteButtonがClickされた時という情報が必要かどうかでいうとそうではない。
関心の分離
そのため、ここではonComplete
という「何かしらが完了した時」という情報にとどめておいた方がいい。
関心の分離について
関心の分離
関心の分離とは「関心事、つまりユースケースや目的、役割ごとに分離する」というソフトウェア工学における考え方
名前の設計
「商品」を表すクラスに対してそのまま「商品」と命名してしまうと、影響の範囲が巨大化してしまう
可能な限り具体的で、意味範囲が狭い、特化した名前を選ぶ
特定の関心事でしか用いられないような、極めて意味範囲の狭い名前をクラスに付与することで、以下のような効果が生まれます。
- 名前とは無関係なロジックを排除しやすくなる。
- クラスが小さくなる。
- 関係するクラスの個数が少なくなる(クラス結合度低減)。
- 関係クラス個数が少ないので、仕様変更時に考慮を要する影響範囲が小さく済む。
- 関心事に特化した名前であるために、どこを変更すれば良いか直ぐ探し出せる。
- 開発生産性が向上する。
例えば「金額」という曖昧でどうとでも解釈可能な、意味範囲ガバガバな名前ではなく、請求金額、消費税額、延滞保証料、シルバー割引料金など、個別具体的な名前を用い、クラスに命名しましょう。
どんな関心事があるかドメイン分析することが大切
ドメインモデル貧血症に陥らないよう注意
意味の粒度を細かく分けすぎてしまった結果、「~情報」や「~データ」など情報を表現する名前になることが度々見受けられます。しかしこれはやってはいけません。こうしたクラスは得てして「OrderInfo」や「PersonData」などと名付けられ、そして名前の印象からデータしか持たないクラスになります。