這篇文章跟大家介紹的內容是關於React的使用:React元件內部的狀態管理,有著一定的參考價值,有需要的朋友可以參考一下。
在本文中,我們將把目光聚焦於 React 元件內部的狀態管理,去認識或重新思考以下三個核心概念:
props
和 state
#
函數組件
類別組件
讓我們開始吧!
01. React 中的資料
站在「元件」的角度上,React 把應用程式中流動的資料分為兩種:
不可更改內容,但可以單向跨元件傳遞的 props;
可以更改內容,但不能跨元件傳遞的 state;
進一步說,props 和 state 的差別在於,props 是外在的,並且被任何渲染這個元件的程式碼所控制。而 state 則是內部的,並且被組件本身所控制。
非電腦專業的初學者經常困惑 props 和 state 在名稱與意義上的關聯,其實大可不必在意,他們本質上只是資料的別稱,只是在 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上下文問題」。
記住:如果你的元件不需要追蹤內部狀態,盡量使用函數元件。
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 使我们迫使大脑关注两个重要的部分:
组件看起来是什么样?
组件当前的状态是什么?
通过让组件管理自己的状态,任何时候状态的变更都会令 React 自动更新相应的页面部分。这便是使用 React 构建组件的主要优势之一:当页面需要重新渲染时,我们仅仅需要思考的是如何更改状态。我们不必跟踪页面的哪些部分需要更改,不需要决定如何有效的重新呈现页面,React 自会比较先前的输出和新的输出,决定什么应该发生改变,并为我们做出决定。而这个确定之前改变了什么和现在应该新输出什么的过程有一个专门的名词,叫做 Reconciliation。
04. 修改 state
你应该还记得类组件与函数组件最大的不同在于类组件自身拥有可以改变内部数据的能力。那么如何行使这一能力呢?和直觉不同,要做到这一点,你需要使用 React 提供的专门的 API:this.setState()。
你有两种方式使用该 API:
设置对象参数;
设置函数参数;
让我们先来看看第一种:
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 被调用时实际上做了两件事:
修改 state 对象;
驱动组件重新渲染;
如果你对 React 有一定研究,你可能会质疑我以上所罗列的两点并不精确,的确如此,小小的 this.setState() API 其实内部还有很多细节值得注意,例如,当调用 this.setState() 时并不会立即改变 state 的值,也当然不会立即重新渲染组件。例如,当以对象为参数调用 this.setState() API 时,尽管内部重复为数据赋值,最终的数据也只保留最后一次更改的结果。
不过幸好,这些略显古怪的状态早有前人为我们做了详尽的解释,如果你感兴趣,请点击下方链接查询更多的信息:
setState:这个API设计到底怎么样
问一个react更新State的问题?
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 的两种数据形式:state 和 props,并且介绍了 React 组件的两种形式:函数组件与类组件,希望各位有所收获。
相关推荐:
以上是React的使用:React元件內部的狀態管理的詳細內容。更多資訊請關注PHP中文網其他相關文章!