搜尋
首頁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>
         </p><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>
      
    )
 

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

const Logo = () => (
      <p>
       <img  alt="建構React元件最全方法" >
      </p>
    )
 

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

傳遞expense物件

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

const ExpenseDetails = ({ expense }) => (
      <p>
         </p><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>
      
    )
 

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

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

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

const ExpenseDetails = ({ expense, dateFormat }) => (
      <p>
         </p><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>
      
    )
 

#

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

const ExpenseDetails = ({ expense, dateFormat, withCurrency, currencyFormat, isOverdue, isPaid ... })

 

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

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

只传递必要的属性

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

const ExpenseDetails = ({ category, description, amount, date }) => (
      <p>
         </p><p>Category: <span>{category}</span></p>
         <p>Description: <span>{description}</span></p>
         <p>Amount: <span>{amount}</span></p>
         <p>Date: <span>{date}</span></p>
      
    )

 

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

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

<expensedetails></expensedetails>

 

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

传递map或者array的属性

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

const ExpenseDetails = ({ expense }) => (
      <p>
      {
        _.reduce(expense, (acc, value, key) => {
          acc.push(</p><p>{key}<span>{value}</span></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>
        { 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
JavaScript是用C編寫的嗎?檢查證據JavaScript是用C編寫的嗎?檢查證據Apr 25, 2025 am 12:15 AM

是的,JavaScript的引擎核心是用C語言編寫的。 1)C語言提供了高效性能和底層控制,適合JavaScript引擎的開發。 2)以V8引擎為例,其核心用C 編寫,結合了C的效率和麵向對象特性。 3)JavaScript引擎的工作原理包括解析、編譯和執行,C語言在這些過程中發揮關鍵作用。

JavaScript的角色:使網絡交互和動態JavaScript的角色:使網絡交互和動態Apr 24, 2025 am 12:12 AM

JavaScript是現代網站的核心,因為它增強了網頁的交互性和動態性。 1)它允許在不刷新頁面的情況下改變內容,2)通過DOMAPI操作網頁,3)支持複雜的交互效果如動畫和拖放,4)優化性能和最佳實踐提高用戶體驗。

C和JavaScript:連接解釋C和JavaScript:連接解釋Apr 23, 2025 am 12:07 AM

C 和JavaScript通過WebAssembly實現互操作性。 1)C 代碼編譯成WebAssembly模塊,引入到JavaScript環境中,增強計算能力。 2)在遊戲開發中,C 處理物理引擎和圖形渲染,JavaScript負責遊戲邏輯和用戶界面。

從網站到應用程序:JavaScript的不同應用從網站到應用程序:JavaScript的不同應用Apr 22, 2025 am 12:02 AM

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

Python vs. JavaScript:比較用例和應用程序Python vs. JavaScript:比較用例和應用程序Apr 21, 2025 am 12:01 AM

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。

C/C在JavaScript口譯員和編譯器中的作用C/C在JavaScript口譯員和編譯器中的作用Apr 20, 2025 am 12:01 AM

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。1)C 用于解析JavaScript源码并生成抽象语法树。2)C 负责生成和执行字节码。3)C 实现JIT编译器,在运行时优化和编译热点代码,显著提高JavaScript的执行效率。

JavaScript在行動中:現實世界中的示例和項目JavaScript在行動中:現實世界中的示例和項目Apr 19, 2025 am 12:13 AM

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

JavaScript和Web:核心功能和用例JavaScript和Web:核心功能和用例Apr 18, 2025 am 12:19 AM

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

See all articles

熱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

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

熱工具

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

記事本++7.3.1

記事本++7.3.1

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

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具