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'));