はじめに
Storybookで作成されたStory(Storeへconnect
されたコンポーネントを配下に持つコンポーネント)をReduxの<Privider />
でラップし、Storybook用のモックデータ(initialState
)を出力するまでを備忘録を兼ねて書きます。
環境構築
実行環境
- Mac OS Sierra: v10.12.6
- node: v8.11.2
- npm: v5.6.0
- yarn: v1.5.1
Reactアプリの構築
create-react-app storybook-react-redux-sample
# 作成したプロジェクトのルートに移動
cd storybook-react-redux-sample
Storybook環境の構築
# StorybookのCLIをグローバルインストール
npm i -g @storybook/cli
getstorybook
ここまで無事に成功すると
yarn storybook
をコマンドラインで実行し、http://localhost:9009/
をブラウザのアドレスバーに打ち込んでアクセスできます。
ReactとReduxの接続
Redux Todos ExampleをベースにReducer、Storeおよびコンポーネントを作成します。
Reducer
サンプルのものを一部改変し、process.env.NODE_ENV
を使って、Storybook環境の場合のinitialState
(モックデータ)を定義します。
const initialState =
process.env.NODE_ENV === "storybook"
? [
{
id: 1,
text: "hogehoge",
completed: true
}
]
: [];
const todos = (state = initialState, action) => {
switch (action.type) {
case "ADD_TODO":
return [
...state,
{
id: action.id,
text: action.text,
completed: false
}
];
case "TOGGLE_TODO":
return state.map(
todo =>
todo.id === action.id ? { ...todo, completed: !todo.completed } : todo
);
default:
return state;
}
};
export default todos;
Store
import React from "react";
import { render } from "react-dom";
import { createStore } from "redux";
import { Provider } from "react-redux";
import App from "./components/App";
import rootReducer from "./reducers";
export const store = createStore(
rootReducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
環境変数(NODE_ENV
)
Storybook起動時に、環境変数であるNODE_ENV
にstorybook
が適用されるよう、Storybook起動用のScriptにNODE_ENV=storybook
を追加します。
"scripts": {
...
"storybook": "NODE_ENV=storybook start-storybook -p 9009 -s public",
...
},
Storyを追加
ルートコンポーネントの要素である<App />
が、Reduxへ接続するための<Provider />
にラップされるよう、addDecoratorのAPIを使います。
import React from "react";
import { storiesOf } from "@storybook/react";
import { action } from "@storybook/addon-actions";
import { linkTo } from "@storybook/addon-links";
import { Button, Welcome } from "@storybook/react/demo";
import { Provider } from "react-redux";
import App from "../../src/components/App";
import { store } from "../../src/index";
storiesOf("App", module)
.addDecorator(story => <Provider store={store}>{story()}</Provider>)
.add("connected to Redux Store", () => <App />);
上記{story()}
部分が<App />
で置き換えられます。
サンプルコード
