一个所谓的「公共业务组件」,应该包含了 UI 和数据两部分。比如淘宝上的收货地址选择控件,应该就包含了三个 select 选择器和对应的省市区数据。这样一个地址选择控件的逻辑在各个模块中都是一致的,但是怎么设计才能实现复用呢?
考虑一种极端情况,页面上同时有两个模块都使用了这个公共的地址选择组件。当在这个组件里选择了一个省份时,会 dispatch 一个 SELECT_PROVINCE 的 action,那么两个模块怎么知道用户到底是选择了哪个模块里公共组件的省份呢?
再考虑另外一个问题,当用户选择了一个省份后,某一个业务模块希望能够再做一些别的数据处理(比如根据当前选择的省份加载对应的热销宝贝)该怎么操作呢?总不能在 reducer 中 dispatch 一个 action 吧?
其实这两个问题的解决思路是类似的,就是在公共组件中,数据传递的过程中加上更多的限制,我能想到的有这么两种解决方案:
###公共组件自己维护状态,业务模块通过给公共组件传入回调来获得公共组件的数据变动,再 dispatch 响应的 action 更新自己的 state。这样设计的问题在于,违背了 Redux 倡导的无状态原则,公共组件内部存在了 state 和 setState 操作。
###通过 props 传入指定的 actionType 或 actionCreator(传入 actionCreator 是我同事奇阳的想法)来让公共组件 dispatch 不同的 action,以此达到区分的效果。
一个简单的例子:
// 公共模块自己定义的 actionCreator
import { provinceActionCreator } from './actionCreator';
// 一个公共的地址选择组件
const AddressPicker = React.createClass({
handleChangeProvince(e) {
// 优先使用 props 中传入的 actionCreator
const provinceActionCreator = this.props.provinceActionCreator || provinceActionCreator;
// dispatch 一个选择省份的 action
this.props.dispatch(provinceActionCreator(e.target.value));
},
render() {
return (
<select onChange={this.handleChangeProvince}>
<option>北京</option>
<option>浙江</option>
</select>
);
}
});
那么除了上面两种方案,还有更佳的处理方案?
原文地址:https://undefinedblog.com/some-thoughts-in-redux/
因遇到商榷的问题和该文章相同,所以直接引用该作者的例子。