1、初始温度计算器
- 判断煮沸组件
1234567function BoilingVerdict (props) {if (props.celsius >= 100) {return <p>The water would boil.</p>}return <p>The water would not boil.</p>} - 输入计算组件,并渲染BoilingVerdict
123456789101112131415161718192021222324252627282930class Calculator extends React.Component {constructor (props) {super(props)this.state = { temperature: '' }this.handleChange = this.handleChange.bind(this)}handleChange (e) {this.setState({temperature: e.target.value})}render () {const temperature = this.state.temperaturereturn (<fieldset><legend>Enter temperatur in Celsius:</legend><input value={ temperature } onChange={ this.handleChange } /><BoilingVerdict celsius={ parseFloat(temperature) } /></fieldset>)}}ReactDOM.render(<Calculator />,document.getElementById('root'))
2、加入华氏温度输入框
- 从
Calculator
组件抽离出TemperatureInput
组件
12345678910111213141516171819202122232425262728293031323334353637383940414243444546const scaleNames = {c: 'Celsius',f: 'Fahrenheit'}class TemperatureInput extends React.Component {constructor (props) {super(props)this.state = { temperature: '' }this.handleChange = this.handleChange.bind(this)}handleChange (e) {this.setState({temperature: e.target.value})}render () {const temperature = this.state.temperatureconst scale = this.props.scalereturn (<fieldset><legend>Enter temperature in { scaleNames[scale] }:</legend><input value={ temperature } onChange={ this.handleChange } /></fieldset>)}}class Calculator2 extends React.Component {render () {return (<div><TemperatureInput scale="c" /><TemperatureInput scale="f" /></div>)}}ReactDOM.render(<Calculator2 />,document.getElementById('root2'))
3、状态提升
- 温度转换
123456789101112131415161718192021// 转摄氏度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) / 1000return rounded.toString()} - 受控组件共享state
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970class TemperatureInput2 extends React.Component {constructor (props) {super(props)// this.state = { temperature: '' }this.handleChange = this.handleChange.bind(this)}handleChange (e) {// this.setState({ temperature: e.target.value })this.props.onTemperatureChange(e.target.value)}render () {// const temperature = this.state.temperatureconst temperature = this.props.temperatureconst scale = this.props.scalereturn (<fieldset><legend>Enter temperature in { scaleNames[scale] }:</legend><input value={ temperature } onChange={ this.handleChange } /></fieldset>)}}class Calculator3 extends React.Component {constructor (props) {super(props)this.state = { temperature: '', scale: 'c' }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.scaleconst temperature = this.state.temperatureconst celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperatureconst fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperaturereturn (<div><TemperatureInput2scale="c"temperature={ celsius }onTemperatureChange={ this.handleCelsiusChange } /><TemperatureInput2scale="f"temperature={ fahrenheit }onTemperatureChange={ this.handleFahrenheitChange } /><BoilingVerdictcelsius={ parseFloat(celsius) } /></div>)}}ReactDOM.render(<Calculator3 />,document.getElementById('root3'))
4、学习小结
- 在 React 应用中,任何可变数据应当只有一个相对应的唯一“数据源”。
- 通常,state 都是首先添加到需要渲染数据的组件中去。然后,如果其他组件也需要这个 state,那么你可以将它提升至这些组件的最近共同父组件中。
- 使用 React 开发者工具 来检查问题组件的 props