Componentの責務について

該当のPR external_link

スクリーンショット 2020-01-16 22.52.31.png

該当の箇所

トリガーイベントに関するチェックボックスが並んでいる。

スクリーンショット 2020-01-16 23.01.06.png

TriggerEventChieckBox.jsx

TriggerEventCheckBox.jsx
import React from 'react'; import PropTypes from 'prop-types'; import { withTranslation } from 'react-i18next'; const TriggerEventCheckBox = (props) => { const { t } = props; return ( <div className="checkbox checkbox-inverse"> <input type="checkbox" id={`trigger-event-${props.event}`} value={props.event} checked={props.checked} onChange={props.onChange} /> <label htmlFor={`trigger-event-${props.event}`}> {props.children}{' '} {t(`notification_setting.event_${props.event}`)} </label> </div> ); }; TriggerEventCheckBox.propTypes = { t: PropTypes.func.isRequired, // i18next checked: PropTypes.bool.isRequired, onChange: PropTypes.func.isRequired, event: PropTypes.string.isRequired, children: PropTypes.object.isRequired, }; export default withTranslation()(TriggerEventCheckBox);

このファイルでは chickbox を表示させることのみを行なっている。

  • チェックボックスのON/OFF状態
  • チェックボックスを押した時に何が起こるか

以上のような状態や関数を持たないステートレスなコンポーネントである。

ManageGlobalNotification.jsx

ManageGlobalNotification.jsx
<TriggerEventCheckBox event="pageCreate" checked={this.state.triggerEvents.has('pageCreate')} onChange={() => this.onChangeTriggerEvents('pageCreate')} > <span className="label label-success"> <i className="icon-doc"></i> CREATE </span> </TriggerEventCheckBox>

triggerEvents: new Set([])
stateには、Setオブジェクトを用い一意の値を格納するようにしている。
今回は TriggerPattern に関する Checkbox なので重複することはないため適切だと考えた。

Set を使わないやり方は/React/スプレッド構文の使い所 external_linkで実践している。

親コンポーネントが持つ triggerEvents に該当のトリガータイプがあれば checked は true になる。
子コンポーネントは、 props から boolean を受け取ってチェックボックスを表示する。
onChenge にはトリガータイプを変更するメソッドを定義し、子コンポーネントは受け取った関数をそのまま使う。

責務の分離

今回のコードでは、振る舞いと表示の責務をコンポーネントレベルで分けている。
以下のようなメリットが考えられる。

  • 記述量が減るため可読性が高まる。
    単純にコード量が減るため、読みやすいファイルになる。
    そのため、別の場所での再利用しやすい。

  • メンテナブルなコンポーネントになる。
    振る舞いに関する記述が減るため、UIに特化したファイルになる。
    そのためcheckboxというパーツの把握に専念でき、データの流れが一方通行でバグを防げる。

  • パフォーマンスが高い ライフサイクルについて心配する必要がないために、処理が高速で不必要なrenderを防げる。
    また、関連して問題のないコンポーネントはできる限りPureComponent external_linkを使用することを推奨されている。

PropTypesについて

また、型を記述する PropTypes も見逃せない。
props の型を把握するでコンポーネントの振る舞いを補強してくれる。
checked がboolean型だと分かることで安心できるだけでなく、その用途が checkbox の ON/OFF を表現することまで把握できる。 書き手にもメリットがある。
書くタイミングで改めて要件を把握でき、このコンポーネントが持つ責務を整理できる。
コードコメントのメリットに近いものがある。