コンポーネント設計がReact Nativeの開発速度に直結する
CTOの Shoken です。キッチハイクでは1年半前に0ベースからReact Nativeでアプリ開発を始めました。React Nativeアプリを長期的に開発・メンテナンスする際に重要になるのがコンポーネント設計です。1年半の開発を通して、デザイナーとエンジニアがコンポーネント設計での共通認識を持っていることが、機能追加・修正などの開発速度に直結するという学びを得ました。この記事では、キッチハイクアプリのコンポーネント設計の考え方を紹介します。
- コンポーネント設計がReact Nativeの開発速度に直結する
- Atomic Designという共通言語
- コンポーネントを構成する4つの要素
- "デザインとしての構造性" と "コードとしての再利用性"
- ButtonはAtomなのかMoleculeなのか問題
- Atomic Design以外の観点
- デザイナーとエンジニアのコンポーネント設計
- まとめ
- We’re Hiring!
- 参考記事
Atomic Designという共通言語
デザイナーとエンジニアの共通言語には、Atomic Designを選びました。この選択によって、デザイナー・エンジニアに共通の概念ができ、コミュニケーションに大きく役に立ったと感じます。一方で、Atom, Molecule, Organismの範囲・感覚を合わせるのには苦労しました。そこでわかったのは、どうやらデザイナーとエンジニアではコンポーネント分割のロジックが違うようです。ディスカッションを進めるうちにこれは、それぞれの視点が違うことによって起きていることだとわかりました。
そこで、まずはコンポーネントの要素とその責務を整理することから始めました。
コンポーネントを構成する4つの要素
なぜ、デザイナーとエンジニアの間でコンポーネント設計にすれ違いが起きるのか。我々のチームでは、それぞれの視点が違うことが原因していたと思います。コンポーネントの構成を以下の4つで考えていくと、デザイナーとエンジニアの担当範囲に違いがあることがわかりました。
要素 | 説明 |
---|---|
情報構造 | HTMLが責務を持つ部分 |
スタイル | CSSが責務を持つ部分 |
状態 | Reactコンポーネントが管理。外部との通信が発生する場合もある |
インタラクション・機能 | React・CSSが責務を持つ |
我々のチームでは、デザイナーは情報構造・スタイル・インタラクションの一部に注目し、エンジニアは状態・インタラクション・機能に注目していました。デザイナーの考える変更に強いデザイン観点での最適化と、エンジニアの考える変更に強い実装観点での最適化が、時折一致しないようでした。議論を進める上で、この整理と認識は表情に重要なものとなりました。
"デザインとしての構造性" と "コードとしての再利用性"
複数の役割をカプセル化したものであることが、コンポーネントの設計を難しくしている要因であると考えています。 React Nativeのコンポーネントは、自身が状態を持ち、状態を変更するトリガーへの責務を持っています。
さらに外部との通信やコールバックの受け渡しも行うため、コードとしての再利用性や制限を考慮する必要があります。コンポーネント設計の目的がデザインとしての構造性の向上に偏ってしまうと、場合によってはコードとして再利用がしにくいコンポーネントになる可能性があります。
チームで検討した結果、 コンポーネントの再利用性を考慮した場合に、実装要素の方が影響が大きいと判断し、エンジニアが最終的なコンポーネント設計の責任を負う方針にしました。
ButtonはAtomなのかMoleculeなのか問題
一般的にButtonコンポーネントの中にはアイコンや文字列が入ってきます。アイコンや文字列をAtomにすると、ButtonはMoleculeになるけど、本当にそれで良いのか、という問題です。
この問題も、前述のエンジニア的コンポーネント再利用性という視点から検討すると、「アイコンや文字列をコンポーネントにしてButtonを組み立てるのは使いにくそう。Buttonを最小コンポーネントとして再利用したい。なのでAtomにしよう。」とチーム全員の共通認識になったのは大きかったです。
Atomic Design以外の観点
ここで、エンジニアがAtomic Design以外で考慮しているコンポーネント設計時のポイントを紹介します。Atomic Designはその一部です。
- Atomic Design
- 冪等性とステートレス
- 責務の分割(ロジックとViewの分離)
- 変更の頻度
1. Atomic Design
一般的なAtomic DesignでAtoms, Molecules, Organismsを意識して設計しています。現在はディレクトリ分割までは行なっていませんが、各コンポーネントがまとまっていた方が管理しやすいようにも思えるので、将来的にはディレクトリ分割をしていきたいと考えています。
2. 冪等性とステートレス
Stateless Functional Componentsの切り出しです。できる限りステートレスなコンポーネントにする方針をとっています。設計時にstateを持たなくても良いコンポーネントはStateless Functional Componentsとしています。Atomic Designとは以下の対応関係になっています。
定義方法 | state | 再利用 | |
---|---|---|---|
Atoms | Functional Component | もたない | あり |
Molecules | Functional Component | もたない | あり |
Organisms | Class Component | もつ | ない |
Templates | Class Component | もつ | ない |
可能な限り、stateを使わずにpropsのみを使ったFunctional Componentとして切り出して、コンポーネントを副作用の無い、値をDOMに変換する装置に徹することを目指しています。
ただ、現状はMoleculesでもstateを持っていたりするので、徹底は難しいと感じています。
3. 責務の分割(ロジックとViewの分離)
キッチハイクのサーバーサイドはRailsで開発しています。Viewファイルにロジックを記述している時にMVCとの違いを感じます。理想はViewモデルクラスを作成してロジックとViewを分離したいのですが、まだまだコンポーネントそのものに長いロジックを記述しがちです。可能な限りAPI(サーバー側)にロジックを持たせてView(アプリ側)にはロジックを持たせないようにしていますが、アプリ側でやらなければならないことも多く悩みどころです。
4. 変更の頻度
頻繁に変更されるであろう箇所を切り出すようにしています。Railsでの開発で意識しているオブジェクト指向からの考え方ですが、コンポーネント指向にも共通し変更に強いシステムを構築するために必要な観点だと考えています。
デザイナーとエンジニアのコンポーネント設計
ここから、キッチハイクチームでのデザイナーとエンジニアのコンポーネント設計過程を紹介します。
デザイナー
デザイナーはユーザーインタビューやメンバーからの要望をもとに、要件整理を行います。要件が固まってきた段階で、エンジニアメンバーがMTGに入ることも多いです。要件はKibelaにまとめます。
整理された要件をもとに、Sketchでデザインを作成し、ZeplinでSketchのシンボルをもとにデザインパーツカタログを作成します。
エンジニア
エンジニアはデザイナーが作成したデザインパーツカタログをもとにコンポーネントを設計します。デザイナーがAtomic Designを考慮してパーツを作成しているので、エンジニアは冪等性・ステートレス、責務の分割、変更の頻度を考慮して、再利用性の観点でAtom, Molecules, Organismsと分けていきます。
現状では実装したコンポーネントのデザインレビューは、デザイナーがアプリをビルドして確認していますが、今後の長期的な開発を見据えるとコンポーネントカタログ化するメリットが大きいので、少しずつStorybookで確認できるように進めています。
まとめ
キッチハイクでのReact Nativeアプリ開発で、デザイナーとエンジニアがどういう方針でコンポーネント設計を進めているかを紹介しました。
- コンポーネントはデザインと実装にまたがる複数の責務を持つ
- デザインとしての構造性とコードとしての再利用性は場合によってはコンフリクトする
- コンポーネント設計において、Atomic Design以外では冪等性、責務の分割、変更の頻度を考慮
さらなるベストプラクティスを求めて、デザイナーとエンジニアがより密にコミュニケーションを取りながら設計できるチームを目指していきます。
We’re Hiring!
キッチハイクでは、React Nativeエンジニア・フロントエンドエンジニア・Railsエンジニア・インターンエンジニアを募集中です!
参考記事
今回のブログ記事を作成するにあたり、参考にした資料を以下に記載します。