学习React 的第十四天 React状态提升

170 阅读2分钟

“开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 14 天,点击查看活动详情

1. 简介

在我们的实际开发中,经常需要用到响应式数据(多个组件使用同一个数据,当其中一个组件改变了,另一个组件也需要同步更新),本次就学习使用状态提升,把数据放到最近的共同父组件中去,实现不同组件的响应式数据。

2. 代码案例

1. 先创建通用组件

import { useState } from "react";

interface propsType {
    name: string
}

export function TemperatureInput({ name }: propsType) {
    const [state, setState] = useState('');

    const handleChange = (e: any) => {
        setState(e.target.value);
    }

    return (
        <fieldset>
            <legend>请在【{name}】中输入温度:</legend>
            <input value={state} onChange={handleChange}/>
        </fieldset>
    );
}
function App() {
    return <AppDiv>
        <TemperatureInput name="温度计一"/>
        <TemperatureInput name="温度计二"/>
    </AppDiv>
}

image.png

  1. 目前来看有了两个输入框,但在其中一个输入数据时,另一个并不会更新,这还未达到我们需要的功能。
  2. 两个 TemperatureInput 组件均在各自内部的 state 中相互独立地保存着各自的数据。

2.我们两个输入框内的数值彼此能够同步。

  1. 把多个组件中需要共享的 state 向上移动到它们的最近共同父组件中,实现共享State,这就是所谓的状态提升,学到这里是不是感觉和Vue的数据共享挂载到bus 是同样的逻辑。
  2. 修改我们的代码,实现状态提升
interface propsType {
    name: string,
    state: string,
    onStateChange: Function
}

export function TemperatureInput({ name, onStateChange, state }: propsType) {

    const handleChange = (e: any) => {
        onStateChange(e.target.value);
    }

    return (
        <fieldset>
            <legend>请在【{name}】中输入温度:</legend>
            <input value={state} onChange={handleChange}/>
        </fieldset>
    );
}
function App() {
    const [state, setState] = useState("");
    return <AppDiv>
        <TemperatureInput name="温度计一" state={state} onStateChange={setState}/>
        <TemperatureInput name="温度计二" state={state} onStateChange={setState}/>
    </AppDiv>
}

image.png

  1. 取消了TemperatureInput组件的私有状态
  2. 在父组件中创建共享状态
  3. 从而通过props属性引入到子组件中
  4. 每次触发onStateChange事件实则是触发了我们父组件的setState事件
  5. 两个输入框中的数值由同一个 state,因此它们始终保持同步。

3. 总结

  1. 通过状态提升,完成了兄弟组件的状态同步,数据传输。