bind的意义
以下组件在construtor中使用bind将onClick与类成员函数绑定:
import React, { Component } from 'react';
export default class ClickCounter extends Component {
constructor(props) {
super(props);
this.onClick = this.onClick.bind(this);
this.state = {
count: 0
};
}
onClick() {
this.setState({
count: this.state.count + 1
});
}
render() {
return (
<div>
<button onClick={this.onClick}>Click Me</button>
<div>
Click Count : {this.state.count}
</div>
</div>
)
}
}
原因:
ES6的类成员函数与类实例并不是自动绑定的,constructor是组件装载时调用的第一个函数,此时this指向当前的类实例,使用bind就可以把成员函数绑定到这个实例。
prop和state
React 组件的数据分为两种, prop state ,无论 prop 或者 state 的改变,都可能引
发组件的重新渲染。prop 是组件的对外接口, state 是组件的内部状态,对外用
prop ,内部用 state。
prop state 的区别:
- prop 用于定义外部接口, state 用于记录内部状态;
- prop 的赋值在外部世界使用组件时, state 的赋值在组件内部;
- 组件不应该改变 prop 的值,而 state 存在的目的就是让组件来改变的。
组件向外传递数据
props用于将数据从父组件传递给子组件,子组件将内部数据向父组件传递时也可以使用props。这种情况下,父组件要通过props向子组件传递可以调用的函数,子组件通过调用这个函数就能把内部数据传回给父组件。
父组件需要取到内部三个子组件的数值进行计算,可以这样做:
import React, {Component} from 'react';
import Counter from './Counter';
export default class ControlPanel extends Component {
constructor(props) {
super(props);
this.onCounterUpdate = this.onCounterUpdate.bind(this);
this.state = ({
sum: 30
});
}
onCounterUpdate(previousValue, newValue) {
this.setState({
sum: this.state.sum + (newValue - previousValue)
});
}
render() {
return (
<div>
<Counter caption="First" onUpdate={this.onCounterUpdate} />
<Counter caption="Second" onUpdate={this.onCounterUpdate} initValue={10} />
<Counter caption="Third" onUpdate={this.onCounterUpdate} initValue={20} />
<hr />
<span>Total count: {this.state.sum} </span>
</div>
)
}
}
父组件的onUpdate
与成员函数onCounterUpdate
绑定,因此在子组件调用onUpdate
函数时,父组件就会通过onCounterUpdate
取得子组件传递的值。
import React, {Component} from 'react';
import PropTypes from 'prop-types';
export default class Counter extends Component {
constructor(props) {
super(props);
this.onAdd = this.onAdd.bind(this);
this.onDecrease = this.onDecrease.bind(this);
this.state = {
count: props.initValue || 0
};
}
onAdd() {
this.updateValue(true);
}
onDecrease() {
this.updateValue(false);
}
updateValue(isAdd) {
const previousValue = this.state.count;
const newValue = isAdd ? previousValue + 1 : previousValue - 1 ;
this.setState({
count: newValue
});
this.props.onUpdate(previousValue, newValue);
}
render() {
return (
<div>
<button onClick={this.onAdd}>+</button>
<button onClick={this.onDecrease}>-</button>
<span>{this.props.caption} count:{this.state.count}</span>
</div>
)
}
}
Counter.propTypes = {
caption: PropTypes.string.isRequired,
initValue: PropTypes.number,
onUpdate: PropTypes.func
}
Counter.defaultProps = {
initValue: 0,
onUpdate: f => f
}