React 官网学习 - 组件的状态提升
const scaleNames = {
c: 'Celsius',
f: 'Fahrenheit'
};
function toCelsius(fahrenheit) { //转为摄氏度
return (fahrenheit - 32) * 5 / 9;
}
function toFahrenheit(celsius) { //转为华氏度
return (celsius * 9 / 5) + 32;
}
function tryConvert (temperature, convert) { //转换检查 函数
const input = parseFloat(temperature);
if(Number.isNaN(input)) {
return ''; //返回空
}
const output = convert(input);
const rounded = Math.round(output * 1000) / 1000; //返回三位小数组成的输出值
return rounded.toString();
}
// 父组件
class Calculator extends React.Component {
constructor (props) {
super(props);
this.state = {
temperature: '',
scale: ''
};
this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
}
handleCelsiusChange(temperature){
this.setState({scale: 'c', temperature})
}
handleFahrenheitChange(temperature){
this.setState({scale: 'f', temperature})
}
render() {
const scale = this.state.scale;
const temperature = this.state.temperature;
// 如果输入框是f,那么c框得到转换后的值;否则如果输入框是c,那么值就是 输入多少就是多少。
// 第二条逻辑相同。
const temperatureC = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;
const temperatureF = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;
return (
<div>
{/*通过父组件Calculator,将temperatur传入*/}
<TemperatureInput
scale="c"
temperature={temperatureC}
onTemperatureChange={this.handleCelsiusChange} />
<TemperatureInput
scale="f"
temperature={temperatureF}
onTemperatureChange={this.handleFahrenheitChange} />
</div>
);
}
};
//在React中,将多个组件中需要共享的state向上移动到它们最近的父组件中,便可实现state共享。
class TemperatureInput extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
//Before this.state = {temperature: ''};// 温度数值已经变为从父组件传递,这里就不用初始化了
}
handleChange(e) {
// Before: this.setState({temperature: e.target.value});
this.props.onTemperatureChange(e.target.value); //数据来源父组件的props
}
render() {
//这里我们把this.state.temperature 改为 this.props.temperature ,数据来自外部
// Before: const temperature = this.state.temperature;
const temperature = this.props.temperature;
const scale = this.props.scale;
//我们知道,props是只读的。当temperature存在于TemperatureInput组件的state中时,组件调用
//this.setState()便可修改它。然而,temperature是由父组件传入的prop,
//TemperatureInput 组件便失去了对它的控制权。
//使用 “受控组件”去解决。与DOM中的<input>接收value和onChange一样,自定义的TemperatureInput组件
//接受temperature和onTemperatureChange这两个来自父组件Calculator的props。
//现在,当TemperatureInput组件想更新温度时,需调用this.props.onTemperatureChange来更新它:
return (
<fieldset>
<legend>Enter temperature in {scaleNames[scale]}:</legend>
<input value={temperature}
onChange={this.handleChange} />
</fieldset>
);
}
}
ReactDOM.render(<Calculator />, document.getElementById('root'));