为什么 redux-thunk 在 Storybook 中不起作用?
Why is redux-thunk not working in Storybook?
我已经将 Storybook UI 开发工具集成到我的 create-react-app.
一切正常,直到我将 addon-redux 作为附加组件添加到 Storybook。
.storybook/main.js
module.exports = {
stories: ["../src/components/**/*.stories.js"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/preset-create-react-app",
"addon-redux", // This one
],
};
包含该行后,开始在我的容器组件中显示此消息。
这是我的容器组件。
TickerList.jsx
/* eslint-disable react-hooks/exhaustive-deps */
import { useEffect } from "react";
import { connect } from "react-redux";
import { handleGetTickers } from "../../../actions/tickers";
import Ticker from "../../atoms/Ticker";
function TickerList({ tickers, getTickers }) {
useEffect(() => {
getTickers();
}, []);
return (
<div className="ticker-list">
{tickers.map((item, i) => (
<Ticker
key={i}
name={item.name}
value={item.value}
percentage={item.percentage}
/>
))}
</div>
);
}
function mapStateToProps(state) {
return {
tickers: state.tickers,
};
}
function mapDispatchToProps(dispatch) {
return {
getTickers: () => dispatch(handleGetTickers()),
};
}
export default connect(mapStateToProps, mapDispatchToProps)(TickerList);
这是我的 handleTickers 动作创建器。
export const GET_TICKERS = "GET_TICKERS";
function getTickers(tickers) {
return {
type: GET_TICKERS,
payload: tickers,
};
}
// handleGetTickers
export function handleGetTickers() {
return async (dispatch) => {
const res = await fetchData("/data/tickers.json");
if (res.ok) {
const result = await res.json();
dispatch(getTickers(result.data));
}
}
众所周知,我们需要包含 thunk 来处理这些类型的操作。所以我在创建我的 Redux Store 时包括了它。这家商店也导入 Storybook。
store.js
import { createStore, compose, applyMiddleware } from "redux";
import { enhancer as withReduxEnhancer } from "addon-redux"; // This is use for connect the App Redux Store with Storybook
import invariant from "redux-immutable-state-invariant";
import { createLogger } from "redux-logger";
import thunk from "redux-thunk";
import reducer from "./reducers";
const createMiddlewareEnhancer = () => {
const middleware = [thunk];
if (process.env.NODE_ENV !== "production") {
middleware.push(invariant());
middleware.push(createLogger());
}
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;
那为什么它不仅在 Storybook 中而且在浏览器中也能完美运行?我在这里错过了什么吗?
感谢任何帮助。
Redux-thunk 是一个中间件,但是 addon-redux
has issues with middlewares for now。但也有可能的解决方案。
If you're using redux-thunk, your React UI made be triggering actions
where the action is a function instead of an object. Since addon-redux
ignores middlewares, the redux-thunk middleware gets ignore and then
an error is thrown that Redux found an action that is a function.
我已经将 Storybook UI 开发工具集成到我的 create-react-app.
一切正常,直到我将 addon-redux 作为附加组件添加到 Storybook。
.storybook/main.js
module.exports = {
stories: ["../src/components/**/*.stories.js"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/preset-create-react-app",
"addon-redux", // This one
],
};
包含该行后,开始在我的容器组件中显示此消息。
这是我的容器组件。
TickerList.jsx
/* eslint-disable react-hooks/exhaustive-deps */
import { useEffect } from "react";
import { connect } from "react-redux";
import { handleGetTickers } from "../../../actions/tickers";
import Ticker from "../../atoms/Ticker";
function TickerList({ tickers, getTickers }) {
useEffect(() => {
getTickers();
}, []);
return (
<div className="ticker-list">
{tickers.map((item, i) => (
<Ticker
key={i}
name={item.name}
value={item.value}
percentage={item.percentage}
/>
))}
</div>
);
}
function mapStateToProps(state) {
return {
tickers: state.tickers,
};
}
function mapDispatchToProps(dispatch) {
return {
getTickers: () => dispatch(handleGetTickers()),
};
}
export default connect(mapStateToProps, mapDispatchToProps)(TickerList);
这是我的 handleTickers 动作创建器。
export const GET_TICKERS = "GET_TICKERS";
function getTickers(tickers) {
return {
type: GET_TICKERS,
payload: tickers,
};
}
// handleGetTickers
export function handleGetTickers() {
return async (dispatch) => {
const res = await fetchData("/data/tickers.json");
if (res.ok) {
const result = await res.json();
dispatch(getTickers(result.data));
}
}
众所周知,我们需要包含 thunk 来处理这些类型的操作。所以我在创建我的 Redux Store 时包括了它。这家商店也导入 Storybook。
store.js
import { createStore, compose, applyMiddleware } from "redux";
import { enhancer as withReduxEnhancer } from "addon-redux"; // This is use for connect the App Redux Store with Storybook
import invariant from "redux-immutable-state-invariant";
import { createLogger } from "redux-logger";
import thunk from "redux-thunk";
import reducer from "./reducers";
const createMiddlewareEnhancer = () => {
const middleware = [thunk];
if (process.env.NODE_ENV !== "production") {
middleware.push(invariant());
middleware.push(createLogger());
}
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;
那为什么它不仅在 Storybook 中而且在浏览器中也能完美运行?我在这里错过了什么吗?
感谢任何帮助。
Redux-thunk 是一个中间件,但是 addon-redux
has issues with middlewares for now。但也有可能的解决方案。
If you're using redux-thunk, your React UI made be triggering actions where the action is a function instead of an object. Since addon-redux ignores middlewares, the redux-thunk middleware gets ignore and then an error is thrown that Redux found an action that is a function.