2.4.1 应用实例
您可以在百度里搜索“深入浅出React和Redux 艾草文学(www.321553.xyz)”查找最新章节!
2.4.1 应用实例
展示这个功能的代码存在于https://github.com/mocheng/react-and-redux/代码库的chapter-02/controlpanel_with_summary目录下,在界面上,可以看到效果如图2-4所示:
图2-4 包含总数的ControlPanel应用效果图
点击任何一个Counter的“+”按钮或者“-”按钮,可以看见除了所属Counter的计数变化,底部的总计数也会随之变化,这是因为Counter能够把自己状态改变的信息传递给外层的组件。
接下来看实现这个功能的关键代码。
在Counter组件中,对于点击“+”和“-”按钮的事件处理方法做了改动,代码如下:
onClickIncrementButton() {
this.updateCount(true);
}
onClickDecrementButton() {
this.updateCount(false);
}
updateCount(isIncrement) {
const previousValue = this.state.count;
const newValue = isIncrement ? previousValue + 1 : previousValue - 1;
this.setState({count: newValue})
this.props.onUpdate(newValue, previousValue)
}
现在,onClickIncrementButton函数和onClickDecrementButton的任务除了调用this.setState改变内部状态,还要调用this.props.onUpdate这个函数,为了避免重复代码,我们对原有代码做了一下重构,提取了共同部分到updateCount函数里。
对应的,Counter组件的propTypes和defaultProps就要增加onUpdate的定义,代码如下:
Counter.propTypes = {
caption: PropTypes.string.isRequired,
initValue: PropTypes.number,
onUpdate: PropTypes.func
};
Counter.defaultProps = {
initValue: 0,
onUpdate: f => f //默认是一个什么都不做的函数
};
新增加的prop叫做onUpdate,类型是一个函数,当Counter的状态改变的时候,就会调用这个给定的函数,从而达到通知父组件的作用。
这样,Counter的onUpdate就成了作为子组件的Counter向父组件ControlPanel传递数据的渠道,我们先约定这个函数的第一个参数是Counter更新之后的新值,第二个参数是更新之前的值,至于如何使用这两个参数的值,是父组件ControlPanel的逻辑,Counter不用操心,而且根据两个参数的值足够可以推导出数值是增加还是减少。
从使用Counter组件的角度,在ControlPanel组件中也要做一些修改,现在Control-Panel需要包含自己的state,首先是构造函数部分,代码如下:
constructor(props) {
super(props);
this.onCounterUpdate = this.onCounterUpdate.bind(this);
this.initValues = [ 0, 10, 20];
const initSum = this.initValues.reduce((a, b) => a+b, 0);
this.state = {
sum: initSum
};
}
在ControlPanel组件被第一次渲染的时候,就需要显示三个计数器数值的总和,所以我们在构造函数中用initValues数组记录所有的Counter的初始值,在初始化this.state之前,将initValues数组中所有值加在一起,作为this.state中sum字段的初始值。
ControlPanel传递给Counter组件onUpdate这个prop的值是onCounterUpdate函数,代码如下:
onCounterUpdate(newValue, previousValue) {
const valueChange = newValue - previousValue;
this.setState({ sum: this.state.sum + valueChange});
}
onCounterUpdate函数的参数和Counter中调用onUpdate prop的参数规格一致,第一个参数为新值,第二个参数为之前的值,两者之差就是改变值,将这个改变作用到this.state.sum上就是新的sum状态。
遗憾的是,React虽然有PropType能够检查prop的类型,却没有任何机制来限制prop的参数规格,参数的一致性只能靠开发者来保证。
ControlPanel组件的render函数中需要增加对this.state.sum和onCounterUpdate的使用,代码如下:
render() {
return (
Total Count: {this.state.sum}
);
}
} 深入浅出React和Redux