一般公共组件
<Switch
className="switch"
activeIndex={this.state.activeIndex}
onChange={::this.handleSwitchChange}
>
<SwitchItem>趋势</SwitchItem>
<SwitchItem>列表</SwitchItem>
</Switch>
generate component 写法
export const generateSwitch = (name, options) => {
const propTypes = {
className: PropTypes.string,
activeKey: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
onChange: PropTypes.func.isRequired,
};
const Switch = (props) => {
...
return (
<span className={classes}>
{
options.map((entry, index) => (
...
))
}
</span>
);
};
Switch.propTypes = propTypes;
Switch.displayName = name;
return Switch;
};
export const ASwitch = generateSwitch('ABSwitch', [
{ name: 'AA', key: 'a' },
{ name: 'BB', key: 'b' },
]);
export const BSwitch = generateSwitch('CDSwitch', [
{ name: 'CC', key: 'c' },
{ name: 'DD', key: 'd' },
]);
UI Component 的 Generator。
actionCreators 与 UI 放在了一起,
然后通过 pageName 和 moduleName 来唯一地标识一个模块,
拼装这两个参数作为 action 的前缀,从而达到每个模块的 action 是全局唯一的。
function generateAbcModule({pageName, moduleName}) {
const ACTION_PREFIX = `${pageName}/${moduleName}`;
const LOAD = ACTION_PREFIX + 'LOAD';
...
function load(url, params, id) {
return (dispatch, getState) => {
const state = getState();
...
return dispatch({
type: LOAD,
....
});
};
}
@connect((state, props) => {
const moduleState = state[pageName][moduleName];
return {
...moduleState,
};
}, {
load,
})
class AbcModule extends Component {
...
}
return AbcModule;
}
reducer 的 Generator。
reducer Generator 通过 pageName 和 moduleName 来唯一地标识一个模块。
每个模块可能会有不同的initialState,这个也可以通过 generateAbcModuleReducer 的入参来设置。
function generateAbcModuleReducer({pageName, moduleName, defaultIndexes}) {
const ACTION_PREFIX = `${pageName}/${moduleName}/`;
const LOAD = ACTION_PREFIX + 'LOAD';
const initialState = {
indexes: defaultIndexes,
...
};
return function AbcModuleReducer(state = initialState, action) {
switch (action.type) {
case LOAD:
return {
...state,
isLoading: true,
...
};
...
}
};