状态提升知识点案例解析理解

状态提升知识点理解


本章节大喵将带着大家,来梳理React组件数据的状态提升,做一些简单的测试研究的归纳总结;首先我们需要来了解一下,变量提升是一个什么样的东东?好,我们接着往下看,

就是如果两个子组件A和B,需要利用到对方的状态的话,那么这个时候我们就需要使用到状态提升,具体的做法就是把A、B两个子组件的状态写到它们的父组件C当中,然后父组件C把状态传递到子组件A和B的props中去,这样子组件A和B也相当于有状态,父组件C也就相当于是数据源。

如果还不理解,请看如下解释:

在react中是单向数据流的设计, 即 只有父组件可以传递数据给子组件,而没有子组件传递数据给父组件的概念,也就是主人与仆人的关系。

那么子组件要传递数据给父组件该如何沟通呢?

换句话说就是, react 如何将子组件的值暴露让父组件获取到?

可以采用一种迂回的方法, 在父组件中设置一个方法(函数), 将其通过props传递给子组件, 然后在子组件中更新state的状态,并调用父组件中传过来的方法, 将state数据作为参数传递给父组件. 这样, 改变父组件的状态,从而改变受父组件控制的所有子组件的状态. 这就是状态提升的概念. 用官方的原话就是: 共享 state(状态) 是通过将其移动到需要它的组件的最接近的共同祖先组件来实现的。 这被称为“状态提升(Lifting State Up);

举例说明

在这里插入图片描述

1、先写一个温度输入子组件:

class TemperatureInput extends React.Component {
    state = {
        temperature: ''
    };
    handleChange = (e) => {
        this.setState({
            temperature : e.target.value
        })
    };
    render() {
        return (
            <fieldset>
                <legend>输入{scaleNames[this.props.scale]}:</legend>
                <input type="number" value={this.state.temperature} onChange={this.handleChange}
            </fieldset>
        )
    }
}

2、我们再接着写另外一个父组件:

class Calculator extends React.Component {
    render () {
        return (
            <div>
                <TemperatureInput scale='c'/>
                <TemperatureInput scale='f'/>
            </div>
        )
    }
}

上面的父组件和子组件,现在没有什么存在的价值,我们仅仅是给两个温度输入组件提供一个父组件,以便我们进行后续的状态提升。

在这里插入图片描述

交互需求:

我们可以输入摄氏度和华氏度,但是我们现在想要让这两个温度保持一致,就是我们如果输入摄氏度,那么下面的华氏度可以自动算出来,如果我们输入华氏度,那么摄氏度就可以自动算出来。

那么我们按照现在这种结构的话,是非常难以实现的,因为我们知道这两个组件之间没有任何关系,它们之间是不知道对方的存在,所以我们需要把它们的状态进行提升,提升到它们的父组件当中。

3、变量提升改造:首先把子组件(温度输入组件)的状态(state)全部删除,看看是什么样子:

class TemperatureInput extends React.Component {

    handleChange = (e) => {};

    render() {
        return (
            <fieldset>
                <legend>输入{scaleNames[this.props.scale]}:</legend>
                <input type="number" value={this.props.temperature} onChange={this.handleChange}/>
            </fieldset>
        )
    }
}

4、变量提升改造:我们通过给 温度输入组件 传入某个函数来让 温度输入组件 中的input发生变化的时候调用

class TemperatureInput extends React.Component {

    handleChange = (e) => {
        this.props.onTemperatureChange(e.target.value);
    };

    render() {
        return (
            <fieldset>
                <legend>输入{scaleNames[ this.props.scale ]}:</legend>
                <input type="number" value={ this.props.temperature } onChange={ this.handleChange } />
            </fieldset>
        )
    }
}

ok,我们的子组件差不多就是这样了,当然我们也可以省略那个handleChange函数,我们完全把inputonChange这么写onChange={this.props.onTemperatureChange},这么写的话注意onTemperatrueChange函数的参数是那个事件event,而不是我这里写的 e.target.value

5、变量提升改造:修改父组件,补上state,以及子组件对应的onChange处理方法,以及子组件的值


class Calculator extends React.Component {
        state = {
            celsius: '',
            fahrenheit: ''
        };

        onCelsiusChange = (value) => {
            this.setState({
                celsius: value,
                fahrenheit: tryConvert(value, toFahrenheit)
            });
        };

        onFahrenheitChange = (value) => {
            this.setState({
                celsius: tryConvert(value, toCelsius),
                fahrenheit: value
            });
        };

        render() {
            return (
                <div>
                    <TemperatureInput scale='c' temperature={this.state.celsius} onTemperatureChange={this.onCelsiusChange}/>
                    <TemperatureInput scale='f' temperature={this.state.fahrenheit} onTemperatureChange={this.onFahrenheitChange}/>
                </div>
            )
        }
    }

这里我们省略的摄氏度与华氏度的转换函数,最后加上我们的 水是否能够烧开的组件。

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章