logo
/
Container・Presentationalコンポーネント

構成

// import 

// Type
type Props = {...}
type PresentationalProps = {...} & Props

// Presentational
const PresentationlComponent:React.FC<PresentationalProps> = (props) => {
	return <Some style={}>{Some}</>
}

// Default(Container)
const Some:React.FC<Props> = (props) => {
	const some = useSome()
	const presentationalProps = {...props,some}
	return PresentationLComponent {...presentationalProps} />
}

export {PresentationLComponent}
export type {Props}
export default Some;
Storybook First な開発のススメではPropsをPresentational側のtypeにしていたが逆にしている。「Container層」を作るというよりは、コンポーネントに「Presentational層」を追加する方向性なのでこうしている。

Presentationalコンポーネント

Domや見た目の実装

Default(Containerコンポーネント)

hooksやハンドラの実装

メリット

  • PresentationlComponentを使えばstorybook上ですべての見た目の状態を管理できる
  • API がなくても開発できる
    • API から帰ってくる値を Storybook から流し込むので、API がなくてもそのコンポーネントやページの妥当性を確認できる

デメリット

  • propsのバケツリレーが起きる

注意点

大きなコンポーネントを汎用的にしない

コンポーネント指向による実装を考えると、各コンポーネントを汎用的なものとして実装しがちです。
末端の小さなコンポーネント(いわゆるAtomsやMolecules)だとその方向性でも問題ない。粒度の大きなコンポーネント(いわゆるOrganisms)を汎用コンポーネントとして実装しようとすると途端に破綻する
  • コンポーネントは大小様々な修正を繰り返す箇所。共通コンポーネントに見えても、場所によって微妙に仕様が異なることも起こりうる
  • 粒度が大きくなるほど、当然内部の実装も複雑化する。それを一まとめに共通化すると、保守性が悪化する
  • 上記2つが合わさると、複雑な実装+ページ固有の条件分岐による複雑怪奇なコンポーネントが爆誕する

ファイルを分けない

1ファイルに複数コンポーネント書くの嫌な人もいるだろうけど、ファイルを分けるデメリット(数が多くなる)のほうが大きい。
1つの目的のコンポーネントををわざわざツールのために2階層にしているだけなので、ファイルを分ける必要はない。

参考