React官方文档--Lifting State Up

Lifting State Up

如果,几个组件需要同时影响并且修改同一个数据,我们建议将这个共享状态进行提升,给他们最近的共同祖先。
在这个部分,我们将要创建一个温度计算器来判断水会不会在给定温度下沸腾。
我们将从一个叫做BoilingVerdict的组件开始,这个组件接收celsius温度作为属性,然后打印是否足够让水沸腾。
然后我们创建一个组件叫做Calculator,这个组件渲染一个<input>元素让你输入温度,并且将温度存储在this.state.value中,另外,他渲染了BoilingVerdict元素,通过当前输入的值。

function BoilingVerdict(props) {
    if (props.celsius >= 100) {
        return <p>The water would boil.</p>;
    } else {
        return <p>The water would not boil.</p>;
    }
}

class Calculator extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value: ""
        };
        this.handleChange = this.handleChange.bind(this);
    }

    handleChange(event) {
        this.setState({
            value: event.target.value
        });
    }
    render() {
        return (
            <div>
                <label htmlFor="temp">celsius: </label>
                <input type="text" value={this.state.value} name="temp" onChange={this.handleChange}/>
                <br/>
                <BoilingVerdict celsius={this.state.value}/>
            </div>
        );
    }
}

ReactDOM.render(
    <Calculator />,
    document.getElementById("root")
);

添加第二个输入

我们的新的需求是,除了摄氏温度的输入,还添加一个华氏温度的输入,然后这两个保持是异步的。
我们通过拆分一个TempertatureInput组件开始,我们将会添加一个新的scale属性来标记是摄氏还是华氏。

const scaleNames = {
    c: 'Celsius',
    f: 'Fahrenheit'
};
function BoilingVerdict(props) {
  if (props.celsius >= 100) {
    return <p>The water would boil.</p>;
  }
  return <p>The water would not boil.</p>;
}
function toCelsius(fahrenheit) {
    return (fahrenheit - 32) * 5 / 9;
}
function toFahrenheit(celsius) {
    return (celsius * 9 / 5) + 32;
}
function tryConvert(value, convert) {
    const input = parseFloat(value);
    if (Number.isNaN(input)) {
        return '';
    }
    const output = convert(input);
    const rounded = Math.round(output * 1000) / 1000;
    return rounded.toString();
}
class TemperatureInput extends React.Component {
    constructor(props) {
        super(props);
        this.handleChange = this.handleChange.bind(this);
        this.state = {
            value: ''
        }
    }
    //这里封装了父组件的onChange函数
    handleChange(event) {
        this.props.onChange(event.target.value);
    }

    render() {
        const value = this.props.value;
        const scale = this.props.scale;
        return (
            <fieldset>
                <legend>Enter Temperature in {scaleNames[scale]}: </legend>
                <input type="text" value={value} onChange={this.handleChange}/>
            </fieldset>
        );
    }
}

class Calculator extends React.Component {
    constructor(props) {
        super(props);
        this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
        this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
        this.state = {
            value: '',
            scale: 'c'
        };
    }

    handleCelsiusChange(value) {
        console.log(value);
        this.setState({
            scale: 'c',
            value
        });
    }

    handleFahrenheitChange(value) {
        console.log(value);
        this.setState({
            scale: 'f',
            value
        });
    }

    render() {
        const scale = this.state.scale;
        const value = this.state.value;
        const celsius = scale === 'f' ? tryConvert(value, toCelsius) : value;
        const fahrenheit = scale === 'c' ? tryConvert(value, toFahrenheit) : value;
        return (
            <div>
                //这个组件的onChange函数是经过TemperatureInput封装的
                <TemperatureInput scale="c" value={celsius} onChange={this.handleCelsiusChange} />
                <TemperatureInput scale="f" value={fahrenheit} onChange={this.handleFahrenheitChange} />
                <BoilingVerdict celsius={parseFloat(celsius)} />
            </div>
        );
    }
}

ReactDOM.render(
    <Calculator />,
    document.getElementById("root")
);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值