React状态提升
由于React的单向数据流,组件无法修改自己的props,
只能通过父组件传递的方法来修改父组件的state,向下引起props的变化。
在 React 应用中,任何可变数据应当只有一个相对应的唯一“数据源”。通常,state 都是首先添
加到需要渲染数据的组件中去。然后,如果其他组件也需要这个 state,那么你可以将它提升至这
些组件的最近的共同父组件中。应当依靠自上而下的数据流,而不是尝试在不同组件间同步 state。
官方demo的实现(与官方代码有差异):
import React from 'react';
function BoilingVerdict(props) {
if(props.celsius >= 100) {
return <p>The water would boil</p>
}
return <p>The water would not boil</p>
}
const scaleNames = {
c: 'Celsius',
f: 'Fahrenheit'
};
class TemperatureInput extends React.Component {
render() {
const temperature = this.props.temperature;
const scale = this.props.scale;
const onInputChange = this.props.onInputChange;
return(
<fieldset>
<legend>Input temperature in {scaleNames[scale]}</legend>
<input value={temperature} onChange={onInputChange}/>
</fieldset>
)
}
}
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 Demo extends React.Component {
constructor(props) {
super(props);
this.state = {
temperature: '',
scale: ''
};
this.onCelInputChange = this.onCelInputChange.bind(this);
this.onFahInputChange = this.onFahInputChange.bind(this);
}
render() {
let tf;
let tc;
if(this.state.scale === "c") {
tc = this.state.temperature;
tf = tryConvert(tc, toFahrenheit);
} else {
tf = this.state.temperature;
tc = tryConvert(tf, toCelsius);
}
return (
<div>
<TemperatureInput temperature={tc} scale="c" onInputChange={this.onCelInputChange}/>
<TemperatureInput temperature={tf} scale="f" onInputChange={this.onFahInputChange}/>
<BoilingVerdict celsius={tc}/>
</div>
)
}
onCelInputChange(e) {
this.setState({
temperature: e.target.value,
scale: 'c'
})
}
onFahInputChange(e) {
this.setState({
temperature: e.target.value,
scale: 'f'
})
}
}
export default Demo;