1. 程式人生 > >React 深入系列2:元件分類

React 深入系列2:元件分類

React 深入系列,深入講解了React中的重點概念、特性和模式等,旨在幫助大家加深對React的理解,以及在專案中更加靈活地使用React。

React 元件有很多種分類方式,常見的分類方式有函式元件和類元件,無狀態元件和有狀態元件,展示型元件和容器型元件。好吧,這又是一篇咬文嚼字的文章。但是,真正把這幾組概念咬清楚、嚼明白後,對於頁面的元件劃分、元件之間的解耦是大有裨益的。

函式元件和類元件

函式元件(Functional Component )和類元件(Class Component),劃分依據是根據元件的定義方式。函式元件使用函式定義元件,類元件使用ES6 class定義元件。下面是函式元件和類元件的簡單示例:

// 函式元件
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

// 類元件
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

上面的兩種寫法是等價的,但函式元件的寫法要比類元件簡潔,不過類元件比函式元件功能更加強大。類元件可以維護自身的狀態變數,即元件的state,類元件還有不同的生命週期方法,可以讓開發者能夠在元件的不同階段(掛載、更新、解除安裝),對元件做更多的控制。

類元件有這麼多優點,是不是我們在開發中應該首選使用類元件呢?其實不然。函式元件更加專注和單一,承擔的職責也更加清晰,它只是一個返回React 元素的函式,只關注對應UI的展現。函式元件接收外部傳入的props,返回對應UI的DOM描述,僅此而已。當然,如上面例子所示,使用只包含一個render方法的類元件,可以實現和函式元件相同的效果。但函式元件的使用可以從思想上迫使你在設計元件時多做思考,更加關注邏輯和顯示的分離,設計出更加合理的頁面上元件樹的結構。實際操作上,當一個元件不需要管理自身狀態時,可以把它設計成函式元件,當你有足夠的理由發現它需要“升級”為類元件時,再把它改造為類元件。因為函式元件“升級”為類元件是有一定成本的,這樣就會要求你做這個改造前更認真地思考其合理性,而不是僅僅為了一時的方便就使用類元件。

無狀態元件和有狀態元件

無狀態元件(Stateless Component )和有狀態元件(Stateful Component),劃分依據是根據元件內部是否維護state。無狀態元件內部不使用state,只根據外部元件傳入的props返回待渲染的React 元素。有狀態元件內部使用state,維護自身狀態的變化,有狀態元件根據外部元件傳入的props和自身的state,共同決定最終返回的React 元素。

很容易知道,函式元件一定是無狀態元件,類元件則既可以充當無狀態元件,也可以充當有狀態元件。但如上文所述,當一個元件不需要管理自身狀態時,也就是無狀態元件,應該優先設計為函式元件。

展示型元件和容器型元件

展示型元件(Presentational Component)和容器型元件(Container Component),劃分依據是根據元件的職責。

展示型元件的職責是:元件UI長成什麼樣。展示型元件不關心元件使用的資料是如何獲取的,以及元件資料應該如何修改,它只需要知道有了這些資料後,元件UI是什麼樣子的即可。外部元件通過props傳遞給展示型元件所需的資料和修改這些資料的回撥函式,展示型元件只是它們的使用者。展示型元件一般是無狀態元件,不需要state,因為展示型元件不需要管理資料,但當展示型元件需要管理自身的UI狀態時,例如控制組件內部彈框的顯示與隱藏,是可以使用state的,這時的state屬於UI state。既然大部分情況下展示型元件不需要state,應該優先考慮使用函式元件實現展示型元件。

容器型元件的職責是:元件資料如何工作。容器型元件需要知道如何獲取子元件所需資料,以及這些資料的處理邏輯,並把資料和邏輯通過props提供給子元件使用。容器型元件一般是有狀態元件,因為它們需要管理頁面所需資料。

例如,下面的例子中,UserListContainer是一個容器型元件,它獲取使用者列表資料,然後把使用者列表資料傳遞給展示型元件UserList,由UserList負責UI的展現。

class UserListContainer extends React.Component{
  constructor(props){
    super(props);
    this.state = {
      users: []
    }
  }

  componentDidMount() {
    var that = this;
    fetch('/path/to/user-api').then(function(response) {
      response.json().then(function(data) {
        that.setState({users: data})
      });
    });
  }

  render() {
    return (
      <UserList users={this.state.users} />
    )
  }
}

function UserList(props) {
  return (
    <div>
      <ul className="user-list">
        {props.users.map(function(user) {
          return (
            <li key={user.id}>
              <span>{user.name}</span>
            </li>
          );
        })}
      </ul>
    </div>
  )  
}

展示型元件和容器型元件是可以互相巢狀的,展示型元件的子元件既可以包含展示型元件,也可以包含容器型元件,容器型元件也是如此。例如,當一個容器型元件承擔的資料管理工作過於複雜時,可以在它的子元件中定義新的容器型元件,由新元件分擔資料的管理。展示型元件和容器型元件的劃分完全取決於元件所做的事情。

總結

通過上面的介紹,可以發現這三組概念有很多重疊部分。這三組概念都體現了關注點分離的思想:UI展現和資料邏輯的分離。函式元件、無狀態元件和展示型元件主要關注UI展現,類元件、有狀態元件和容器型元件主要關注資料邏輯。但由於它們的劃分依據不同,它們並非完全等價的概念。它們之間的關聯關係可以歸納為:函式元件一定是無狀態元件,展示型元件一般是無狀態元件;類元件既可以是有狀態元件,又可以是無狀態元件,容器型元件一般是有狀態元件。

下篇預告:

React 深入系列3:State 和 Props

我的新書《React進階之路》已上市,請大家多多支援~

歡迎關注我的公眾號:老幹部的大前端,領取21本大前端精選書籍!

這裡寫圖片描述

相關推薦

React 深入系列2元件分類

React 深入系列,深入講解了React中的重點概念、特性和模式等,旨在幫助大家加深對React的理解,以及在專案中更加靈活地使用React。 React 元件有很多種分類方式,常見的分類方式有函式元件和類元件,無狀態元件和有狀態元件,展示型元件和容

React 深入系列事件處理

箭頭函數 com 如果 發布 web click 系列 額外 新的 文:徐超,《React進階之路》作者 授權發布,轉載請註明作者及出處 React 深入系列5:事件處理 React 深入系列,深入講解了React中的重點概念、特性和模式等,旨在幫助大家加深對R

安卓BroadcastReceiver元件使用系列2給多個廣播接收者傳送廣播和有序廣播的使用

給多個廣播接收者傳送廣播、有序廣播的使用在安卓開發中是經常使用的方式,下面我們來介紹一下它的使用方法。 整體思路:在xml檔案中放置兩個Button控制元件,給這兩個Button控制元件設定點選事件,在第一個點選事件中傳遞一個數據,設定一個動作併發送廣播,在第二個點選事件中

react-native系列(2)入門篇Windows系統下配置Android開發環境

本文主要內容是在Window系統下配置Android APP的開發環境,配置過程將會有點麻煩,請大家需要有點耐心。當然大家也可以參考RN官網的配置過程,但實際上很多開發者根據官網步驟並沒能配置出完整的RN開發環境。目前RN的最新版本是0.57,我們將以這個版本為例配置Android的開發環境。

Kafka系列2深入理解Kafka消費者

Kafka系列2:深入理解Kafka消費者 上篇聊了Kafka概況,包含了Kafka的基本概念、設計原理,以及設計核心。本篇單獨聊聊Kafka的生產者,包括如下內容: 生產者是如何生產訊息 如何建立生產者 傳送訊息到Kafka 生產者配置 分割槽 生產者是如何生產訊息的 首先來看一下Kafka生產者元件圖

Azure Stack技術深入淺出系列2談Azure Stack在私有雲/混合雲生態中的定位

azure stack 雲計算 微軟 azure一、 國內私有雲業務前景就在今年4月,工信部發布《雲計算發展三年行動計劃(2017-2019)》,提出2019年雲計算產業規模將達到4300億。雲計算已成為國家新一代信息產業發展的重要戰略。從中國整個IT投入來看,政府、央企、國企以及大型民企占據主要份額,這些企

Block系列2Block內存管理

style gin elf font str 內存管理 art ber implement ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewCont

centos7.4安裝監控軟件系列2nagios

nagios 監控 與系列1的Cacti類似,nagios也是一種監控軟件,涉及插件較多,可靈活監控服務器資源,使用更廣泛;nagios自身是沒有監控功能的,它所有的功能都是通過調用插件來完成的,它的工作模式有兩種:主動監控、被動監控。【被動監控】nagios通過nsca進行被動監控。就是由被檢測端服

JVM系列2HotSpot虛擬機器物件

1.物件建立過程:   ①.類載入檢查:當java虛擬機器遇到一條new指令時,首先會去檢查該指令的引數能否在常量池中定位到這個類的符號引用,並且檢查這個符號引用代表的類是否已被載入、解析、初始化過,如果沒有,則必須先執行相應的類載入過程。 ②.分配記憶體:類載入檢查完成後,虛擬機器將為新物件分配記憶體

SonarQube學習系列2Maven+SonarQube 最佳實踐

本文記錄了Maven工程使用SonarQube完成程式碼評估,並對其中指定模組進行排除和專案許可權管理等 有些程式碼是使用相關外掛或工具生成的,這些程式碼通常存在高冗餘或書寫不規範現象,不符合程式碼質量要求,但不影響使用,應排除在程式碼質量評估之外 本文基於上一

CS231n課程筆記2線性分類

內容列表: 線性分類器簡介 線性評分函式 闡明線性分類器  線性分類 上一篇筆記介紹了影象分類問題。影象分類的任務,就是從已有的固定分類標籤集合中選擇一個並分配給一張影象。我們還介紹了k-Nearest Neighbor (k-NN)分類器,該分類器的基本思想是通

RxJava2 系列 (2)背壓和Flowable

背壓(Back Pressure)的概念最初並不是在響應式程式設計中提出的,它最初用在流體力學中,指的是後端的壓力, 通常用於描述系統排出的流體在出口處或二次側受到的與流動方向相反的壓力。 在響應式程式設計中,我們可以將產生資訊的部分叫做上游或者叫生產者,處理產

WPF自學教程系列2如何在xaml檔案新增引用?

我們在寫WPF控制元件的時候,經常會需要在xaml檔案新增一些引用, 如System.Windows.Forms引用,但是在xaml檔案沒有提供類似於 using System.Windows.Forms; 的語法, 因此我們需要通過 xmlns關鍵字來新增引用。具體實現如

【SciKit-Learn學習筆記】2kNN分類/迴歸,在糖尿病資料集上的表現

學習《scikit-learn機器學習》時的一些實踐。 kNN分類 在三個點周圍生成聚類樣本,然後做的kNN分類。 這種把標準差取得好(不要太小),得到的就不一定是線性可分的資料了。比如圖上右側有個玫紅點和藍點交錯。 from sklearn.datasets.sa

RxJava系列2RxJava簡單入門

一.擴充套件的觀察者模式 Observable和Subscriber能完成任何事情,你的Observable可以是一個數據庫查詢,Subscriber獲得查詢結果然後將其顯示在螢幕上。你的Observable可以是螢幕上的一個點選,Subscrib

Gradle For Android系列2自定義Build配置

在上一章節中我們學習了Gradle的用法,以及如何建立Android專案以及如何從Eclipse中將專案轉換到Android Studio中。這一章節將介紹構建檔案配置的更多細節,以及一些有用的構建任務,並深入Gradle的Android外掛。 在本章中,

Glide 系列-2主流程原始碼分析(4.8.0)

Glide 是 Android 端比較常用的圖片載入框架,這裡我們就不再介紹它的基礎的使用方式。你可以通過檢視其官方文件學習其基礎使用。這裡,我們給出一個 Glide 的最基本的使用示例,並以此來研究這個整個過程發生了什麼: Glide.with(fragment).load(myU

React學習(2)—— 元件的運用和資料傳遞

React官方中文文件地址:    https://doc.react-china.org/     瞭解了元件之後,就需要理解“Props”和“State”的用法。首先來介紹State,State按照字面意思理解為狀態,其代表著元件本身的屬性,S

VIM實用系列2設定自動換行和自動折行

自動換行是每行超過 n 個字的時候 vim 自動加上換行符用 類似 :set textwidth=70 來設定 n自動折行 是把長的一行用多行顯示 , 不在檔案里加換行符用 :set wrap 設定自動折行:set nowrap 設定不自動折行 windows裡的記事本里的

GANs學習系列(2)cGANs:Conditional Generative Adversarial Networks

結論by ym: 轉完這篇,理解一下表達一下自己的一點感想。 其實cgan潛在的道理很簡單,但是這個簡單直接的改進被證明非常有效。 簡單來說就是因為: 在生成模型中,先驗輸入噪聲p(z)和條件資訊y聯合組成了聯合隱層表徵。對抗訓練框架在隱層表徵的組成方式方面相當地靈活。 即cnn一直以來的