React Storybook入門:コンポーネントカタログがさくさく作れちゃうかもしれないオシャレサンドボックス環境

  • 121
    Like
  • 0
    Comment
More than 1 year has passed since last update.

React Storybook は React をコンポーネント単位でサンドボックスで開発できる開発環境です。

React Storybookの特徴って

実際のReact Componentをサンドボックス内で呼び出してレンダリングします。よってコンポーネントの色々な状態(0件とか新着ありとか)も少ないコードでカタログ化が可能。また、actionというAPIを使ってコンポーネントのイベントをキャッチしてログに流してくれたりもします。
状態込みのスタイルガイドって非常にメンテナンスが面倒なので、これ使えたらかなり革新的じゃないかなぁ……

React Storybook起動画面

  • iframe を利用したサンドボックス内にコンポーネントを隔離します
  • モジュールは自動でリロードされます(関数型のステートレスなモジュールも含め)
  • ReduxRelayMeteorなどを使っていても利用可能
  • さまざまなタイプのCSS()に対応しています
  • 早くてかっこいいUI
  • プロジェクト内で動作するので、npmbabelなどアプリの環境を使いまわせます
  • 静的ファイルのサービングも可能
  • Webpackをカスタマイズしたりプラグインを追加したりと拡張が可能

デモを触ってみる

git clone https://github.com/kadira-samples/react-storybook-demo
npm install
npm run storybook

Reduxで実装された TODOアプリ のデモになります。
React Storybookが無事に起動できたらhttp://localhost:9001にアクセスしてみましょう。

インストール

では、実際に自分のReactプロジェクトにインストールしてみましょう。

  1. @kadira/storybookをインストール
  2. 必要なモジュールをインストール
  3. package.jsonに実行用スクリプトを追加
npm i --save-dev @kadira/storybook
npm i --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react babel-preset-stage-2 react react-dom stack-source-map webpack webpack-hot-middleware
package.json
{
  ...
  "scripts": {
    "storybook": "start-storybook -p 9001"
  }
  ...
}

使ってみる

ストーリーを作る (components/stories/story.js)

まずはstoryを作ります。
どこに作っても良いのですが、基本的にコンポーネントと1:1で対応するものなので、components/stories/みたいなフォルダを作って、そこに入れていくのが推奨されています。
サンプルドキュメントからボタン2種類が登録されたストーリーを作ってみましょう。

components/stories/button.js
import React from 'react';
import { storiesOf, action } from '@kadira/storybook';

storiesOf('Button', module)
  .add('with a text', () => (
    <button>My First Button</button>
  ))
  .add('with no text', () => (
    <button></button>
  ));

storiesOfで指定するのがコンポーネントですね。さらにチェインして.add()でモジュールの状態を追加しておきます。
例えば、validateFieldというコンポーネントに対して、「未入力」「not valid」「valid」の3種類を.add()するみたいな感じです。

Storyを読み込む (.storybook/config.js)

これで起動しようとしても.storybook/config.jsを作れと言われるので、ドキュメントを参考に作ります。

.storybook/config.js
import { configure } from '@kadira/storybook';
import 'css/style.css';

function loadStories() {
  require('../components/stories/button');
}

configure(loadStories, module);

loadStories()内で先ほど作ったストーリーをインポートします。たくさんコンポーネントがある場合は並べてもいいし、フォルダまとめて登録する方法なんかもドキュメントに書いてあります。
スタイルシートを設定する場合は、importで可能なのですが、Reactには色々なCSSの流儀があるので詳細はドキュメントを読みましょう。

起動する

npm run storybook

やっとこれで準備できました。
http://localhost:9001にアクセスできて左側にbuttonが表示されていればOK。

イベントをキャッチする (action())

Storybookにはさらにコンポーネントのイベントをキャッチする機能が搭載されています。先ほどのbutton.jsを以下のように書き換えてみましょう。

components/stories/button.js
import React from 'react';
import { storiesOf, action } from '@kadira/storybook';

storiesOf('Button', module)
  .add('with a text', () => (
    <button onClick={action('click')}>My First Button</button>
  ))
  .add('with no text', () => (
    <button></button>
  ));

テキスト付きボタンの方を押すと、下の"ACTION LOGGER"にログが流れたと思います。

自作のコンポーネントをストーリーに登録する

ボタンのサンプルでは自作のコンポーネントを読み込んでいませんが、普通にimport文で読み込んで、それを使用したストーリーを.add()すればOKです。サンプルの TODOアプリ には4つのストーリーが登録されていますが、それぞれ特徴的になっているので参考になると思います。

エンジニアとデザイナーのコミュニケーション改善に役立つんじゃない?

うまくいくかは分からないですが、以下みたいな使い方すると「あれがなかった!」「これ伝え忘れた」みたいなの防げそうな予感。

  1. エンジニアが必要なストーリーを書いてそれをデザイナーに渡す
  2. デザイナーはそれに対して(ストーリー内で)デザイン&コーディングを行う
  3. エンジニアがそのコードをコンポーネント化する
  4. それ以降はこのストーリー上でデザインの変更を行う

また、状態のパターンやどんなアクションがあるかなど、ストーリーを見ると一目瞭然なので、仕様書代わりとしても機能するんじゃないかな、と思います。

最後に「こんな風にしたらうまくいくぜ」的なマントラがドキュメント中にあったので意訳しておきます。

  • コンポーネントはpropsを使ってデータを受け渡ししましょう。分割するのが楽になります
  • UIコンポーネント中にアプリに依存したコードは書かないようにしましょう
  • ストーリーはコンポーネント近くに置きましょう。componentsフォルダの中なんかは最適です
  • Meteorを使う場合はストーリーをtestsフォルダの中にするか.storiesにしないとダメです
  • ひとつのストーリーではひとつのコンポーネントに対するストーリーを書きましょう
  • ストーリーにプレフィックスをつけるならドットがオススメ(例:storiesOf('core.Button', module)
  • イベントハンドラのデバッグには必ずactions()を使いましょう