Atomic Component Design
ReactやVue.jsでコンポーネントを作る際、テスタブルで再利用しやすいコンポーネントを作るための設計思想を解説します。 この設計思想ではAtomic Designをベースとしています。
設計の基本的な考え方
この設計思想ではコンポーネントが次の2つの情報を扱うかどうかを観点に分類します。
- 状態を持つか
- ドメインの情報をもつか
ここでいう「ドメインの情報」とはシステムやサービス固有の情報という意味です。例えば、ユーザーの情報、会社の情報、書籍の情報など この2つの情報を扱うかどうかで、コンポーネントの責務を明確にし、テスタブルで再利用しやすいコンポーネントを作っていきます。
Atoms
AtomsではラベルやチェックボックスなどのUIパーツの最小単位を定義します。 このコンポーネントでは状態を持たず、ドメインの情報を持ちません。 そのため、このコンポーネントはUIのスタイリング、データの整形処理を責務とします。 なので、UIのテストをする場合はこの点にフォーカスしてテストを行うようします。
例えばチェックボックスのようにUIパーツ自体に状態を持つものは、全て外から渡すようにします。
const Checkbox = ({ label, value, checked, onChange }) => {
return (
<label>
<CheckBox
value={value}
onChange={onChange}
checked={checked}
/>
{label}
</label>
)
}
Molecules
Moleculesでは複数のAtomsを組み合わせたUIパーツを定義します。 Moleculesでは状態を持つが、ドメインの情報を持ちません。 なのでMoleculesは状態の更新、状態に基づいた表示の管理、イベントの発行などを責務を持ちますが、特定のドメインの情報は外から注入されることになります。
例えば、書籍名のサジェスト機能を作る際は、基本的なサジェストロジックであるテキストボックスで入力を受け付けたり、候補のリストを表示する部分はMoleculesとして作成し、 実際の書籍名の情報をサーバーから取得したり、リストを生成する部分は後述のOrganismsが担当します。 Moleculesがドメインの情報を持たないため、「会社名のサジェスト機能を作りたい」のような別のドメインのコンポーネントを作る際もMoleculesをうまく使い回すことができます。 このように責務を分けることで、Moleculeは状態の管理やロジックに注力でき、通信を行う必要がないためテストを行いやすくなります。
Organisms
Organismsでは複数のMoleculesやaotmsを組み合わせ、これらのUIパーツにドメインの情報を注入することを責務とします。 Organismsはドメインの情報を外部から取得したり、ドメインの情報をMoleculesが受け取るデータ形式に変換する責務だけをフォーカスするので、その部分のみテストすれば良くなります。
Pages
PagesではNext.jsやNuxt.jsのpages配下におくページコンポーネントになります。 ページを管理する責務を持ち、状態を持ち、ドメイン情報も持ちます。 Organismsと責務が似ていますが、Pagesはそのページ固有の機能に注力し、他のPagesと共有したいコンポーネントはOrganismsに切り出していくのが良いと思います。