目錄
耦合&內聚
建構元件
只传递必要的属性
传递map或者array的属性
传递一个格式化的子对象
环境为王
首頁 web前端 js教程 建構React元件最全方法

建構React元件最全方法

Jan 23, 2018 am 10:55 AM
react 方法

我非常喜歡使用React,因為我覺得它最大優點就是夠簡單。 在簡單和容易之間還是存在區別 的,我的意思是React也很簡單。當然你需要一些時間來了解它,當你掌握其核心內容後,其他的事都是水到渠成的了。下文將介紹比較困難的部分。

耦合&內聚

這些指標(耦合&內聚)或多或少的給我們改變程式設計習慣帶了挑戰。它們經常被運用在類別形式的物件導向程式設計中。我們也將參考並且運用同樣的規則在編寫React元件上。

耦合指元素之間的相互連結與依賴關係。如果你改變一個元素需要同步的更新另一個元素,我們稱此為緊密耦合。而鬆散耦合指的是改變一個元素時,並不需要改變另一個元素。舉個例子,顯示銀行轉帳金額功能。如果展示金額依賴匯率計算,那麼內部轉換結構變更時,展示的程式碼也會被更新。如果我們設計基於一個元素介面的,鬆散耦合的系統,這樣元素的改變並不會影響視圖層展示。很明顯,鬆散耦合的元件更易於管理和控制。

內聚則是元件是否只為一件事情負責。這個指標是依照單一原則和unix原則:專註一件事情並且做好這件事。如果帳戶餘額格式化展示需要計算相關匯率和檢查是否有查閱歷史權限,那麼這個包含很多功能職責,而這些功能並不相互依賴。也許,權限處理和匯率應該是不同的元件。另一方面,如果有多個組件,一個用於整數部分,一個用於小數部分,另一個用於貨幣展示,程式設計師想展示餘額,他們則需要找到所有組件進行組裝。其中的挑戰則是創造高度內聚的組件。

建構元件

建立元件有很多種方法。我們希望在合理程度下元件是可以被重複使用的 。我們也希望建構的小元件可以用在更大的元件中。理想情況下,我們想建立鬆散耦合和高度聚合的元件,這樣我們的系統更有利於管理和擴展。在React元件中props 類似函數中的參數,它們也可以看做是無狀態功能的元件。我們需要思考在元件中如何定義props和元件如何被重複使用。

接下來,我們以費用管理系統為背景,分析費用詳細的格式,來介紹如果構建組件:

type Expense {
      description: string
      category: string
      amount: number
      doneAt: moment
    }
登入後複製

 

根據模型,會有以下幾種對費用格式的程式建模方式:

  • 無props

  • #傳遞一個expense物件

  • # #傳遞必要的屬性

  • 傳遞所有屬性的map

  • #傳遞一個格式化的子物件

以下分別討論使用上述傳遞方式的優缺點。不過需要時時注意使用以上任何方式是要看使用場景和依賴系統的。這也是我們所做的,建立適當的抽象場景。

無props

這是最簡單的解決辦法,往往就是建立一個寫靜態資料的元件。

const ExpenseDetails = () => (
      <p className=&#39;expense-details&#39;>
         <p>Category: <span>Food</span></p>
         <p>Description: <span>Lunch</span></p>
         <p>Amount: <span>10.15</span></p>
         <p>Date: <span>2017-10-12</span></p>
      </p>
    )
登入後複製
 

不傳遞props,就不會為我們帶來任何彈性,而且元件也只能用於單一的場景。在費用明細的例子中,我們可以看到,最初組件是需要接受一些props。不過在某些場景下,沒有任何props也是一個好的解決方式。首先,我們可以使用一些元件,其props的內容是一些不會輕易更改的內容,例如:商標,logo或公司資訊等。

const Logo = () => (
      <p className=&#39;logo&#39;>
       <img src=&#39;/logo.png&#39; alt=&#39;DayOne logo&#39;/>
      </p>
    )
登入後複製
 

寫出盡可能小的元件使得系統更容易維護。保持資訊只保存在一處而且只需要在一處進行修改。不要在多處寫重複的程式碼。

傳遞expense物件

在費用明細確定情況下,我們需要傳遞資料給元件。首先,我們需要傳遞一個expense物件。

const ExpenseDetails = ({ expense }) => (
      <p className=&#39;expense-details&#39;>
         <p>Category: <span>{expense.category}</span></p>
         <p>Description: <span>{expense.description}</span></p>
         <p>Amount: <span>{expense.amount}</span></p>
         <p>Date: <span>{expense.doneAt}</span></p>
      </p>
    )
登入後複製
 

傳遞費用物件給費用明細的元件是非常有意義的。費用明細的格式是高度一致的,它顯示費用的資料。無論什麼時候需要改變格式,這是唯一可以修改的地方。改變費用明細的格式也不會對費用對象本身帶來什麼副作用。

這個元件是和費用物件緊密耦合,這是一個壞的事情嗎?當然不是,但我們必須意識到這是如何影響我們系統的。 傳遞一個物件作為props,費用明細的元件將會依賴費用內部結構。當我們改變費用的內部結構時候,我們將需要更改費用明細組件。當然,我們只需要在一處進行修改。

這樣的設計如何適應未來的改變呢? 如果我們增加、改變或刪除一個字段,我們將只需改變一個組件。如果我們需要增加一個其他的日曆格式化展示?我們可以為日曆格式化增加一個新的prop。

const ExpenseDetails = ({ expense, dateFormat }) => (
      <p className=&#39;expense-details&#39;>
         <p>Category: <span>{expense.category}</span></p>
         <p>Description: <span>{expense.description}</span></p>
         <p>Amount: <span>{expense.amount}</span></p>
         <p>Date: <span>{expense.doneAt.format(dateFormat)}</span></p>
      </p>
    )
登入後複製
 

#

我们开始增加属性来使组件更加灵活。如果只有几个选项,那么一切都是很ok的。系统业务开始扩展后问题就来了,在不同的场景下我们需要维护大量的props。

const ExpenseDetails = ({ expense, dateFormat, withCurrency, currencyFormat, isOverdue, isPaid ... })
登入後複製

 

增加props可以使得组件重用性更好,但你可能设计了多重功能职责的组件。这种规则也同样在函数写法中运用。可以用多个参数来创建一个函数,当参数的数目超过3个或者4个时候,意味着这个函数在做很多事情了,也许这时候应该将函数拆成更小的函数来的更加简单。

随着组件props的增加,我们将其拆分成定义明确的组件,比如:OverdueExpenseDetails, PaidExpenseDetails等。

只传递必要的属性

为了减少对象自身的内容,我们可以只传递必要的属性值。

const ExpenseDetails = ({ category, description, amount, date }) => (
      <p className=&#39;expense-details&#39;>
         <p>Category: <span>{category}</span></p>
         <p>Description: <span>{description}</span></p>
         <p>Amount: <span>{amount}</span></p>
         <p>Date: <span>{date}</span></p>
      </p>
    )
登入後複製

 

我们分别传递属性,这样我们将一部分工作责任转移给了组件使用者。如果费用的内部结构发生变化,他将不会影响费用明细的格式化。但可能影响每个使用组件的地方,因为我们可能需要修改props。当我们以独立的属性传递props时候,一个组件将更加抽象了。

只传递需要的字段对未来设计改动是如何影响的?增加、更新或者删除字段将不会很容易。无论何时我们要增加一个字段,我们不仅仅要改变费用细节的实现,也需要改变每个使用组件的地方。另外一个方面,支持多种日历格式化几乎是现成的,我们可以传递日历作为prop,也可以传递格式化后的日历。

<ExpenseDetails 
      category={expense.category} 
      description={expense.description}
      amount={expense.amount}
      date={expense.doneAt.format(&#39;YYYY-MM-DD&#39;)}
    />
登入後複製

 

决定如何展示特定的字段应该在掌握在具体使用组件的人手中,这将不是费用明细组件关心的内容。

传递map或者array的属性

为了达到组件抽象化,我们可以传递一个map的属性值。

const ExpenseDetails = ({ expense }) => (
      <p class=&#39;expense-details&#39;>
      {
        _.reduce(expense, (acc, value, key) => {
          acc.push(<p>{key}<span>{value}</span></p>)
        }, [])
      }
      </p>
    )
登入後複製

 

使用组件的人控制费用明细的格式化,传递给组件的对象格式则必须正确。

const expense = {
      "Category": "Food",
      "Description": "Lunch",
      "Amount": 10.15,
      "Date": 2017-10-12
    }
登入後複製

 

这个方案有很多缺陷,我们很难控制组件展示的样式,并且展示顺序也没有指定。因此,如果我们需要某种顺序的话,可以采用array代替map来解决这个问题。但是仍然还有缺陷。

传递map 和array作为props 不与费用耦合,也根本与它不一致。增加和删除新属性虽然只改变了prop,但是我们无法控制组件本身的格式。如果我们只改变类别的格式化,这不是一个可行的办法。(确切地说,总有一个办法来解决,例如,传递另外一个格式化后的props。这个解决方案似乎不再简单了。)

传递一个格式化的子对象

我们也可以只通过直接传对一个子对象,这样就能考虑更少的组件内需要如何展示。

const ExpenseDetails = ({ children }) => (
      <p class=&#39;expense-details&#39;>
        { children }
      </p>
    )
登入後複製

 

在这种情况下,费用明细只是一个提供结构和样式的容器。展示所有信息则是使用组件的人必须提供的。

<ExpenseDetails>
      <p>Category: <span>{expense.category}</span></p>
      <p>Description: <span>{expense.description}</span></p>
      <p>Amount: <span>{expense.amount}</span></p>
      <p>Date: <span>{expense.doneAt}</span></p>
    </ExpenseDetails>
登入後複製

 

在费用明细这个案例中,我们需要重复许多工作,因此这也许不是一个好的解决方案。尽管如此,灵活性则是巨大的,因为有可能有很多不同的格式化操作。增删改只需要改变使用组件时候传入的值。日期格式也是一样的,我们虽然失去了功能内聚的特点,但这也是我们不得不付出的代价。

环境为王

正如你所看到,我们讨论了它们的不同优缺点和可能性。哪一个最好呢,这取决于:

  • 项目本身

  • 项目阶段

  • 组件自身,需要很多特殊的组件组成还是只需要简单的一些选项值

  • 自己的习惯

  • 使用环境-适合频繁的改变和被多次使用

没有一个万能的解决方案,一个方案也并不能适用所有场景。我们如何构建组件对于系统的维护和系统可扩展方面有着深远的影响。这完全依赖于组件所使用的环境。非常幸运的是,我们有很多可使用的方案。组件是功能的抽象集合,它既能构建小系统也能构建大系统。所以这仅仅只是一个选择问题。

相关推荐:

store优化React组件的方法详解

如何在React组件“外”使用父组件的Props

React组件的生命周期函数是什么

以上是建構React元件最全方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

怎麼在番茄免費小說app中寫小說 分享番茄小說寫小說方法教程 怎麼在番茄免費小說app中寫小說 分享番茄小說寫小說方法教程 Mar 28, 2024 pm 12:50 PM

番茄小說是一款非常熱門的小說閱讀軟體,我們在番茄小說中經常會有新的小說和漫畫可以去閱讀,每一本小說和漫畫都很有意思,很多小伙伴也想著要去寫小說來賺取賺取零用錢,在把自己想要寫的小說內容編輯成文字,那麼我們要怎麼樣在這裡面去寫小說呢?小伙伴們都不知道,那就讓我們一起到本站本站中花點時間來看寫小說的方法介紹。分享番茄小說寫小說方法教學  1、先在手機上打開番茄免費小說app,點擊個人中心——作家中心  2、跳到番茄作家助手頁面——點擊創建新書在小說的結

微信刪除的人如何找回(簡單教學告訴你如何恢復被刪除的聯絡人) 微信刪除的人如何找回(簡單教學告訴你如何恢復被刪除的聯絡人) May 01, 2024 pm 12:01 PM

而後悔莫及、人們常常會因為一些原因不小心刪除某些聯絡人、微信作為一款廣泛使用的社群軟體。幫助用戶解決這個問題,本文將介紹如何透過簡單的方法找回被刪除的聯絡人。 1.了解微信聯絡人刪除機制這為我們找回被刪除的聯絡人提供了可能性、微信中的聯絡人刪除機制是將其從通訊錄中移除,但並未完全刪除。 2.使用微信內建「通訊錄恢復」功能微信提供了「通訊錄恢復」節省時間和精力,使用者可以透過此功能快速找回先前刪除的聯絡人,功能。 3.進入微信設定頁面點選右下角,開啟微信應用程式「我」再點選右上角設定圖示、進入設定頁面,,

手機版龍蛋孵化方法大揭密(一步一步教你如何成功孵化手機版龍蛋) 手機版龍蛋孵化方法大揭密(一步一步教你如何成功孵化手機版龍蛋) May 04, 2024 pm 06:01 PM

手機遊戲成為了人們生活中不可或缺的一部分,隨著科技的發展。它以其可愛的龍蛋形象和有趣的孵化過程吸引了眾多玩家的關注,而其中一款備受矚目的遊戲就是手機版龍蛋。幫助玩家們在遊戲中更好地培養和成長自己的小龍,本文將向大家介紹手機版龍蛋的孵化方法。 1.選擇合適的龍蛋種類玩家需要仔細選擇自己喜歡並且適合自己的龍蛋種類,根據遊戲中提供的不同種類的龍蛋屬性和能力。 2.提升孵化機的等級玩家需要透過完成任務和收集道具來提升孵化機的等級,孵化機的等級決定了孵化速度和孵化成功率。 3.收集孵化所需的資源玩家需要在遊戲中

手機字體大小設定方法(輕鬆調整手機字體大小) 手機字體大小設定方法(輕鬆調整手機字體大小) May 07, 2024 pm 03:34 PM

字體大小的設定成為了重要的個人化需求,隨著手機成為人們日常生活的重要工具。以滿足不同使用者的需求、本文將介紹如何透過簡單的操作,提升手機使用體驗,調整手機字體大小。為什麼需要調整手機字體大小-調整字體大小可以使文字更清晰易讀-適合不同年齡段用戶的閱讀需求-方便視力不佳的用戶使用手機系統自帶字體大小設置功能-如何進入系統設置界面-在在設定介面中找到並進入"顯示"選項-找到"字體大小"選項並進行調整第三方應用調整字體大小-下載並安裝支援字體大小調整的應用程式-開啟應用程式並進入相關設定介面-根據個人

Go語言方法與函數的差異及應用場景解析 Go語言方法與函數的差異及應用場景解析 Apr 04, 2024 am 09:24 AM

Go語言方法與函數的差異在於與結構體的關聯性:方法與結構體關聯,用於操作結構體資料或方法;函數獨立於類型,用於執行通用操作。

Java框架與前端React框架的整合 Java框架與前端React框架的整合 Jun 01, 2024 pm 03:16 PM

Java框架與React框架的整合:步驟:設定後端Java框架。建立專案結構。配置建置工具。建立React應用程式。編寫RESTAPI端點。配置通訊機制。實戰案例(SpringBoot+React):Java程式碼:定義RESTfulAPI控制器。 React程式碼:取得並顯示API回傳的資料。

如何選擇手機膜,保護你的手機螢幕(選購手機膜的幾個重點與技巧) 如何選擇手機膜,保護你的手機螢幕(選購手機膜的幾個重點與技巧) May 07, 2024 pm 05:55 PM

手機膜成為了必不可少的配件之一,隨著智慧型手機的普及。延長其使用壽命,選擇合適的手機膜可以保護手機螢幕。幫助讀者選出最適合自己的手機膜、本文將介紹選購手機膜的幾個重點與技巧。了解手機膜的材質及類型PET膜,TPU等、手機膜有多種材質,包括強化玻璃。 PET膜較為柔軟、強化玻璃膜具有較好的耐刮花性能,TPU則具有較好的防震性能。可根據個人偏好及需求來決定,在選擇時。考慮螢幕的保護程度不同類型的手機膜對螢幕的保護程度不同。 PET膜則主要起防刮花作用,強化玻璃膜具有較好的耐摔性能。可以選擇具有較好

快速去除老人斑的有效方法(教你簡單又快速消除老人斑的養膚秘訣) 快速去除老人斑的有效方法(教你簡單又快速消除老人斑的養膚秘訣) May 03, 2024 pm 12:01 PM

頸部和手背等暴露部位,老年斑是一種常見的皮膚問題,往往出現在年長者的臉部。也會讓人看起來顯老、它不僅帶給人們的外表困擾。隨著科技的進步和美容技術的發展,現在有了許多簡單而快速的方法來祛除老年斑,然而。恢復年輕又健康的肌膚、幫助您快速消除老年斑、本文將分享一些有效的養膚秘訣。 1.積極保護皮膚免受紫外線傷害的重要性所以避免長時間暴露在陽光下是非常重要的、紫外線是導致老年斑形成的主要原因之一。 2.合理選擇護膚產品,使用含有抗氧化劑和美白成分的產品護膚產品中含有抗氧化劑和美白成分可以幫助減少老年斑的形

See all articles