React 回忆录(四)React 中的状态管理

Hi 各位,欢迎来到 React 回忆录!👋 在上一章中,我介绍了使用 React 渲染界面元素的方法,以及在这个过程当中蕴含的“组件化”想一想。在本章中,咱们将把目光聚焦于 React 组件内部的状态管理,去认识或从新思考如下三个核心概念:react

  1. propsstate
  2. 函数组件
  3. 类组件

让咱们开始吧! 🙌数组

01. React 中的数据

站在“组件”的角度上,React 把应用中流动的数据分为两种类型:框架

  1. 不可更改内容,但能够单向跨组件传递的 props
  2. 能够更改内容,但不能跨组件传递的 state

进一步说,propsstate 的区别在于,props 是外部的,而且被任何渲染这个组件的代码所控制。而 state 则是内部的,而且被组件自身所控制。函数

非计算机专业的初学者常常困惑 propsstate 在名称与含义上的关联,其实大可没必要在乎,他们本质上只是 数据的别称,只是在 React 中,它们被各自赋予了特殊的限制或能力。

你能够经过组件上的 props 属性,像在 HTML 中传递属性同样,将你想要传递的任何数据传递给子组件,全部的属性都会被存储在子组件(类组件)的 this.props 对象中。工具

function Parent(props) {
    return <Child name={"Tom"} />
}

function Child(props) {
    return <span>(props.name)</span>
}

02. 函数组件

咱们以前提到过,React 使用组件渲染视图提高性能,而组件便是一个函数,能够用一个公式来简洁的表示其功用:f(数据) => UI。到这里我想你应该注意到了,为何咱们说 React 并非一个大型的 MVC (或 MVVM)框架,由于 React 只负责视图层(View)的渲染,其余的事情将由 React 生态中的其余工具来完成。组件化

话说回来,对于 React 组件而言,最简单的一种形式莫过于函数组件了,它充分展示了 React 的哲学,一次只作一件事组件化数据驱动UI性能

函数组件又称为“无状态组件”,“受控组件”或“木偶组件”,由于函数组件只负责接收 props 并返回 UI,它自身并不能拥有可改变的数据,在真实的 React 应用开发场景下,咱们常常尽量的使用函数组件,将整个应用的 UI 拆分红尽量小的视觉单元。this

这是由于函数组件是很是直观的,它接收属性返回元素,内部逻辑清晰明确,并且更重要的是,函数组件内没有 this 关键字,所以你永远不用担忧烦人的“this上下文问题”。spa

记住:若是你的组件不须要追踪内部状态,尽可能使用函数组件。

03. 类组件

和函数组件相对应的,即是“类组件”了,相似的,它也被称为“有状态组件”,“非受控组件”和“容器组件”。这里须要注意,虽然咱们按照代码的形式为两种类型的组件命名,但这并不严谨,由于在 JavaScript 中,“类”也是函数。设计

不一样于函数组件,类组件拥有着能够更改的内部数据 -- state。它最终影响着页面的渲染状况,并且 state 能够被组件在任什么时候刻在内部修改。一般的时刻时用户与界面发生交互的时候。

因为 React 把变化的数据封装在组件内部,并坚持单向数据流的原则。咱们有了高度抽象的 UI 组件,并封装复杂的业务逻辑。这使得咱们能够经过构建,组合一系列小组件开发出大型应用。

那么应该如何向类组件添加 state 呢?很简单,咱们所要作的只是在类组件内部添加一个 state 属性,state 属性是一个对象。这个对象表明了组件的状态,对象的每个属性名都表明组件的一个特定的状态,下面是具体的代码:

import React from "react"

class Parent extends React.Component {
    state = {
        name: "Eliot",
    }
    
    render() {
        return <p>{this.state.name}</p>
    }
}

React 使咱们迫使大脑关注两个重要的部分:

  1. 组件看起来是什么样?
  2. 组件当前的状态是什么?

经过让组件管理本身的状态,任什么时候候状态的变动都会令 React 自动更新相应的页面部分。这即是使用 React 构建组件的主要优点之一:当页面须要从新渲染时,咱们仅仅须要思考的是如何更改状态。咱们没必要跟踪页面的哪些部分须要更改,不须要决定如何有效的从新呈现页面,React 自会比较先前的输出和新的输出,决定什么应该发生改变,并为咱们作出决定。而这个肯定以前改变了什么和如今应该新输出什么的过程有一个专门的名词,叫作 Reconciliation


04. 修改 state

你应该还记得类组件与函数组件最大的不一样在于类组件自身拥有能够改变内部数据的能力。那么如何行使这一能力呢?和直觉不一样,要作到这一点,你须要使用 React 提供的专门的 API:this.setState()

你有两种方式使用该 API:

  1. 设置对象参数;
  2. 设置函数参数;

让咱们先来看看第一种:

this.setState({
    name: "Tom"
})

React 会自动合并对 state 的改变。而有时,你的组件须要一个新的 state ,而这个 state 的变化又依赖于旧的 state 值,每当这种时候,你就该使用第二种 API 调用方式:

this.setState((prevState) => ({
    name: "mr." + prevState.name
}))

讲到这里你可能会感到奇怪,只是更新 state 而已,为何还须要调用一个专门的 API?咱们直接修改以前定义的 state 对象不就行了吗?之因此这样设计的缘由是,组件内 state 的变化不只仅是对象属性值发生变化那么简单,它还须要驱动整个 UI 进行从新渲染,所以 this.setState() 这个 API 被调用时实际上作了两件事:

  1. 修改 state 对象;
  2. 驱动组件从新渲染;

若是你对 React 有必定研究,你可能会质疑我以上所罗列的两点并不精确,的确如此,小小的 this.setState() API 其实内部还有不少细节值得注意,例如,当调用 this.setState() 时并不会当即改变 state 的值,也固然不会当即从新渲染组件。例如,当以对象为参数调用 this.setState() API 时,尽管内部重复为数据赋值,最终的数据也只保留最后一次更改的结果。

不过幸亏,这些略显古怪的状态早有前人为咱们作了详尽的解释,若是你感兴趣,请点击下方连接查询更多的信息:


05. 控制组件

当你在 Web 应用中使用表单时,这个表单的数据被存储于相应的 DOM 节点内部,但正如咱们以前提到的,React 的整个关键点就在于如何高效的管理应用内的状态。因此虽然表单的数据被存储于 DOM 中,React 依然能够对它进行状态管理。

而管理的方式便是使用“控制组件”。简单而言,“控制组件”会渲染出一个表单,可是将表单所需的全部真实数据做为 state 存储于组件内部,而不是 DOM 中。

之因此被称为“控制组件”的缘由也即在于此,“控制组件”控制着组件内的表单数据,所以,惟一更新表单数据的方式就是更新组件内部对应的 state 值。

import React as "react"

class Input extends React.Component {
    state = {
        value: "enter something...",
    }
    
    handleClick: (e) => {
        this.setState({value: e.target.value})
    }
    
    render() {
        <input value={this.state.value} onKeyup={this.handleClick} />
    }
}

能够看到,咱们使用 handleClick 方法响应用户每一次键盘敲击以即时更新表单状态,这样作不只自然的支持了即时的输入验证,还容许你有条件的禁止或点亮表单按钮。


06. 小结

这一章咱们介绍了 React 的两种数据形式:stateprops,而且介绍了 React 组件的两种形式:函数组件类组件,但愿格外有所收获,若是有任何问题或建议,也欢迎各位在评论区内留言,下一章见 🙌

PS:🔊若是你对该专题感兴趣,别忘了订阅本专栏,确保及时收到更新通知。记得点击下方👇的各个按钮,让我知道你承认个人付出,这是激励我持续产出的动力和源泉 😎。

相关文章
相关标签/搜索