addon-redux
是一个 Storybook 插件,用于帮助使用 Redux 状态的组件构建 Storybook。
理想情况下,只需要为未连接 Redux 的组件(而非容器组件)编写 Storybook。然而,在为 Redux 应用程序中的组件编写 Storybook 时,这些组件通常会包含容器组件作为子组件,这会带来问题。addon-redux
通过提供一个装饰器和有用的面板来支持容器组件,从而解决这个问题。
本文档适用于版本 2,有关版本 1 的设置信息,请点击此处。
使用 Redux 插件的 示例 项目。
该插件兼容 Storybook for React
特性
- 向 Storybook 添加两个面板:Redux 状态和 Redux 历史
- 使用 React Redux Provider 组件包裹 Storybook
- 查看和编辑存储的当前状态
- 切换 Storybook 时将 redux 重置为初始状态
- 提供一个 story 参数,用于在加载 Storybook 时更新存储
- 记录 action,并维护时间、action、前一状态、下一状态和状态差异
- 支持时间旅行到之前的状态
安装
npm install addon-redux
使用方法
为了使 React Redux 插件正常工作
注册
与所有 Storybook 插件类似,Redux 插件在使用前需要在 Storybook 中注册。
// .storybook/main.js
module.exports = {
stories: [
"../src/**/*.stories.mdx",
"../src/**/*.stories.@(js|jsx|ts|tsx)"
],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/preset-create-react-app",
"addon-redux"
]
}
增强器
为了让 Redux 插件能够监听和修改存储,在创建存储时必须使用它的增强器,如下所示。
// Simplest use of the Redux Addon Enhancer
import { createStore, compose } from 'redux'
import reducer from './your/reducer'
import { enhancer } from 'addon-redux'
export const store = createStore(reducer, {}, enhancer)
通常,应用程序的存储已经在使用增强器。下面显示了 Redux 插件更实际的存储设置。它包括常用的中间件增强器以及一些用于演示的中间件。此示例展示了 Redux 增强器如何与其他增强器一起使用,尽管不同应用程序之间的存储创建代码可能差异很大。
// Realistic use of the Redux Addon Enhancer with other store enhancers
import { createStore, compose, applyMiddleware } from 'redux'
import { enhancer as withReduxEnhancer } from 'addon-redux'
import reducer from './your/reducer'
import createMiddlewareEnhancer from './middlewareEnhancer'
import invariant from 'redux-immutable-state-invariant'
import logger from 'redux-logger'
createMiddlewareEnhancer () => {
const middleware = []
if (process.env.NODE_ENV !== 'production') {
// include other middlewares as needed, like the invariant and logger middlewares
middleware.push(invariant())
middleware.push(logger())
}
return applyMiddleware(...middleware)
}
const createEnhancer = () => {
const enhancers = []
enhancers.push(createMiddlewareEnhancer())
if (process.env.NODE_ENV !== 'production') {
enhancers.push(withReduxEnhancer)
}
return compose(...enhancers)
}
const store = createStore(reducer, createEnhancer())
export default store
导入存储 (Preview.js)
必须在 ./storybook/preivew.js
中导入存储,以便它可以为 Storybook 设置并准备就绪。只要增强器已按上述方式设置,此插件将自动使用 Redux provider 包裹 Storybook。
这可以通过两种方式完成
- 在文件顶部同步导入存储
// .storybook/preview.js
const store = require('./your/store')
module.exports = {
decorators: []
}
- 使用 Storybook loaders 异步导入存储
// .storybook/preview.js
module.exports = {
decorators: [],
loaders: [
async () => ({
store: await import('../stories/store'),
})
]
};
Args
可以使用 storybook args 对 Redux 状态进行进一步控制。Args 可以通过默认 CSF 导出的 argTypes
键中的 ARG_REDUX_PATH
键链接到 Redux 存储。ARG_REDUX_PATH
的值是一个以点分隔的字符串,表示 args 在存储中对应的路径。整数部分被视为数组索引。
import React from 'react'
import App from './App'
import { ARG_REDUX_PATH } from 'addon-redux'
export default {
title: 'App',
component: App,
argTypes: {
name1: {
control: { type: 'text' },
[ARG_REDUX_PATH]: 'todos.0.text'
}
}
};
const Template = (args) => <App />;
export const All = Template.bind({});
All.args = {
name1: 'First Value',
completed1: false
};
参数
addon-redux
目前支持一个 storybook 参数,可用于在加载 Storybook 时更改 Redux 状态,即 PARAM_REDUX_MERGE_STATE
。此参数接受一个 JSON 字符串或对象,它将被解析并合并到当前存储的状态之上。
// example story using PARAM_REDUX_MERGE_STATE
import React from 'react'
import MyComponent from './MyComponent'
import { PARAM_REDUX_MERGE_STATE } from 'addon-redux'
export default {
title: 'MyComponent',
component: MyComponent,
parameters: {
[PARAM_REDUX_MERGE_STATE]: '{"foo": {"bar": "baz"}}'
}
};
const Template = (args) => <MyComponent {...args} />;
export const All = Template.bind({});
All.args = {};