開發中使用到storybook作爲組件倉庫,然後dva是我們的基礎架構。
想使用storybook測試、開發組件。
這時候發現無法集成dva進來。研究後方案如下。
首先是storybook的一個節點:common.stories.js
import React from 'react';
import { storiesOf } from '@storybook/react';
import { Provider } from 'react-redux';
import { Header, Footer, Mask, Loading, Toast } from '@/components';
import DrawerDemo from '@/components/Drawer/test';
import store from './configureStore';
// store 的操作
store.dispatch({
type: 'system/showToast',
payload: {
content: '我是個測試toast',
duration: 60 * 60 * 1000,
},
});
const styles = {
mobileContainer: { width: 414, height: 736, border: '1px solid #EAEAEA' },
};
storiesOf('common components', module)
.addDecorator(story => <Provider store={store}>{story()}</Provider>)
.add('Toast ', () => <Toast />)
下面是重點1:configureStore.js 從dva中剝離store
import React from 'react';
import dva from 'dva';
import createLoading from 'dva-loading';
import models from '@/models/index';
import Router from '@/routes/routes';
import '@/assets/styles/normalize.css';
// import store from './configureStore';
// eslint-disable-next-line import/no-extraneous-dependencies
const createHistory = require('history').createBrowserHistory;
const app = dva({ history: createHistory() });
app.use(createLoading());
models.forEach(model => {
app.model(model);
});
app.router(() => <Router />);
app.start();
// eslint-disable-next-line no-underscore-dangle
const store = app._store;
// eslint-disable-next-line no-console
console.log('store', store);
export default store;
最後是使用方式,Toast.js
這裏也是個重點,這裏有個問題,就是
dva的connect 和redux的connect不是同一個,這個就很尷尬, 儘管我看源碼是一樣的,但是用下來就是不一樣。
最終的解決方案是使用了環境變量動態的去獲取用誰的connect,代碼如下,分散在三個文件中。
這個是connect.js 用來動態獲取connect
/* eslint-disable import/no-mutable-exports */
// eslint-disable-next-line import/no-mutable-exports
// eslint-disable-next-line prefer-destructuring
let connect = require('dva').connect;
if (!process.env.REACT_APP_PROJECT) {
// eslint-disable-next-line no-console
console.log('the environment is storybook');
// eslint-disable-next-line global-require
connect = require('react-redux').connect;
}
export default connect;
這個是package.json中設置在script中設置環境變量
"scripts": {
"lint": "eslint src --ext .jsx --ext .js --cache --fix",
"format": "prettier-eslint 'src/**/*.{js,jsx}' --write",
"start": "set REACT_APP_PROJECT=true&& node scripts/start.js",
"build": "set REACT_APP_PROJECT=true&&node scripts/build.js",
"test": "set REACT_APP_PROJECT=true&&node scripts/test.js",
"storybook": "start-storybook -p 9010 -s public"
},
最後在組件中這麼用例如 Alert.js
import React, { PureComponent } from 'react';
import connect from '@/utility/connect';
@connect(({ system }) => ({
alert: system.alert,
}))
class Alert extends PureComponent {
...組件內容略
}