React学习-第二篇
状态提升
当某些情况下,当某个变量发生变化时会影响多个组件,那么我们需要把这个变量的状态提升,提升到父组件中。父组件中的变量发生变化,子组件中的状态也跟着变化。也就是说多个组件需要反映相同的变化数据时,可以将共享状态提升到最近的共同父组件中去。
代码是参照React的网站学习的,连接地址:React
先看代码:
import React from 'react'
import ReactDom from 'react-dom'
function BoilingVerdict(props){
if(props.celsius>=100){
return <p>The water would boil.</p>;
}
return <p>The water would not boil.</p>
}
function toCelsisu(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();
}
const scaleNames={
c:'Celsius',
f:'Fahrenheit'
}
class TemperatureInput extends React.Component {
constructor(props){
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(e){
this.props.onTemperatureChange(e.target.value);
}
render(){
const temperature = this.props.temperature;
const scale = this.props.scale;
return (
<fieldset>
<legend>Enter temperature in {scaleNames[scale]}:</legend>
<input value={temperature} onChange={this.handleChange}></input>
</fieldset>
);
}
}
class Calculator extends React.Component {
constructor(props){
super(props);
this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
this.state = {temperature:'',scale:'c'}
}
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;
const celsius = scale === 'f' ? tryConvert(temperature,toCelsisu):temperature;
const fahrenheit = scale === 'c' ? tryConvert(temperature,toFahrenheit):temperature;
return (
<div>
<TemperatureInput
scale='c'
temperature={celsius}
onTemperatureChange={this.handleCelsiusChange}>
</TemperatureInput>
<TemperatureInput
scale='f'
temperature={fahrenheit}
onTemperatureChange={this.handleFahrenheitChange}>
</TemperatureInput>
<BoilingVerdict celsius={parseFloat(celsius)}></BoilingVerdict>
</div>
)
}
}
const element = <Calculator></Calculator>;
ReactDom.render(element,document.getElementById('root'))
代码比较长,不理解也没关系,先往下看
页面如下:
页面上是可以交互的,在一个输入框中输入变量,另一个输入框中的值会自动变化。
上面的代码比较长,大致梳理一下:
- React 会调用 DOM 中 的 onChange 方法。在本实例中,它是 TemperatureInput 组件的 handleChange 方法。
- TemperatureInput 组件中的 handleChange 方法会调用 this.props.onTemperatureChange(),并传入新输入的值作为参数。其 props 诸如 onTemperatureChange 之类,均由父组件 Calculator 提供。
- 起初渲染时,用于摄氏度输入的子组件 TemperatureInput 中的 onTemperatureChange 方法与 Calculator 组件中的 handleCelsiusChange 方法相同,而,用于华氏度输入的子组件 TemperatureInput 中的 onTemperatureChange 方法与 Calculator 组件中的 handleFahrenheitChange 方法相同。因此,无论哪个输入框被编辑都会调用 Calculator 组件中对应的方法。
- 在这些方法内部,Calculator 组件通过使用新的输入值与当前输入框对应的温度计量单位来调用 this.setState() 进而请求 React 重新渲染自己本身。
- React 调用 Calculator 组件的 render 方法得到组件的 UI 呈现。温度转换在这时进行,两个输入框中的数值通过当前输入温度和其计量单位来重新计算获得。
- React 使用 Calculator 组件提供的新 props 分别调用两个 TemperatureInput 子组件的 render 方法来获取子组件的 UI 呈现。
- React 调用 BoilingVerdict 组件的 render 方法,并将摄氏温度值以组件 props 方式传入。
- React DOM 根据输入值匹配水是否沸腾,并将结果更新至 DOM。我们刚刚编辑的输入框接收其当前值,另一个输入框内容更新为转换后的温度值。