日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[译] 你是如何拆分组件的?

發布時間:2025/3/20 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [译] 你是如何拆分组件的? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • 原文地址:How do you separate components?
  • 原文作者:James K Nelson
  • 譯文出自:掘金翻譯計劃
  • 本文永久鏈接:github.com/xitu/gold-m…
  • 譯者:undead25
  • 校對者:薛定諤的貓、Germxu

你是如何拆分組件的?

React 組件會隨著時間的推移而逐步增長。幸好我意識到了這一點,不然我的一些應用程序的組件將變得非常可怕。

但這實際上是一個問題嗎?雖然創建許多只使用一次的小組件似乎有點奇怪……

在一個大型的 React 應用程序中,擁有大量的組件本身沒有什么錯。實際上,對于狀態組件,我們當然是希望它們越小越好。

臃腫組件的出現

關于狀態它通常不會很好地分解。如果有多個動作作用于同一狀態,那么它們都需要放在同一個組件中。狀態可以被改變的方式越多,組件就越大。另外,如果一個組件有影響多個狀態類型的動作,那么它將變得非常龐大,這是不可避免的。

但即使大型組件不可避免,它們使用起來仍然是非常糟糕的。這就是為什么你會盡可能地拆分出更小的組件,遵循關注點分離的原則。

當然,說起來容易做起來難。

尋找關注點分離的方法是一門技術,更是一門藝術。但你可以遵循以下幾種常見模式……

4 種類型的組件

根據我的經驗,有四種類型的組件可以從較大的組件中拆分出來。

視圖組件

有關視圖組件(有些人稱為展示組件)的更多信息,請參閱 Dan Abramov 的名著 —— 展示組件和容器組件。

視圖組件是最簡單的組件類型。它們所做的就是顯示信息,并通過回調發送用戶輸入。它們:

  • 將屬性分發給子元素。
  • 擁有將數據從子元素轉發到父組件的回調。
  • 通常是函數組件,但如果為了性能,它們需要綁定回調,則可能是類。
  • 一般不使用生命周期方法,性能優化除外。
  • 直接存儲狀態,除了以 UI 為中心的狀態,例如動畫狀態。
  • 使用 refs 或直接與 DOM 進行交互(因為 DOM 的改變意味著狀態的改變)。
  • 修改環境。它們不應該直接將動作發送給 redux 的 store 或者調用 API 等。
  • 使用 React 上下文。

你可以從較大的組件中拆分出展示組件的一些跡象:

  • 有 DOM 標記或者樣式。
  • 有像列表項這樣重復的部分。
  • 有“看起來”像一個盒子或者區域的內容。
  • JSX 的一部分僅依賴于單個對象作為輸入數據。
  • 有一個具有不同區域的大型展示組件。

可以從較大的組件中拆分出展示組件的一些示例:

  • 為多個子元素執行布局的組件。
  • 卡片和列表項可以從列表中拆分出來。
  • 字段可以從表單中拆分出來(將所有的更新合并到一個 onChange 回調中)。
  • 標記可以從控件中拆分出來。

控制組件

控制組件指的是存儲與部分輸入相關的狀態的組件,即跟蹤用戶已發起動作的狀態,而這些狀態還未通過 onChange 回調產生有效值。它們與展示組件相似,但是:

  • 可以存儲狀態(當與部分輸入相關時)。
  • 可以使用 refs 和與 DOM 進行交互。
  • 可以使用生命周期方法。
  • 通常沒有任何樣式,也沒有 DOM 標記。

你可以從較大的組件中拆分出控制組件的一些跡象:

  • 將部分輸入存儲在狀態中。
  • 通過 refs 與 DOM 進行交互。
  • 某些部分看起來像原生控件 —— 按鈕,表單域等。

控制組件的一些示例:

  • 日期選擇器
  • 輸入提示
  • 開關

你經常會發現你的很多控件具有相同的行為,但有不同的展現形式。在這種情況下,通過將展現形式拆分成視圖組件,并作為 theme 或 view 屬性傳入是有意義的。

你可以在 react-dnd 庫中查看連接器函數的實際示例。

當從控件中拆分出展示組件時,你可能會發現通過 props 將單獨的 ref 函數和回調傳遞給展示組件感覺有點不對。在這種情況下,它可能有助于傳遞連接器函數,這個函數將 refs 和回調克隆到傳入的元素中。例如:

class MyControl extends React.Component {// 連接器函數使用 React.cloneElement 將事件處理程序// 和 refs 添加到由展示組件創建的元素中。connectControl = (element) => {return React.cloneElement(element, {ref: this.receiveRef,onClick: this.handleClick,})}render() {// 你可以通過屬性將展示組件傳遞給控件,// 從而允許控件以任意標記和樣式來作為主題。return React.createElement(this.props.view, {connectControl: this.connectControl,})}handleClick = (e) => { /* ... */ }receiveRef = (node) => { /* ... */ }// ... }// 展示組件可以在 `connectControl` 中包裹一個元素, // 以添加適當的回調和 `ref` 函數。 function ControlView({ connectControl }) {return connectControl(<div className='some-class'>control content goes here</div>) }復制代碼

你會發現控制組件通常會非常大。它們必須處理和狀態密不可分的 DOM,這就使得控制組件的拆分特別有用;通過將 DOM 交互限制為控制組件,你可以將任何與 DOM 相關的雜項放在一個地方。

控制器

一旦你將展示和控制代碼拆分到獨立的組件中后,大部分剩余的代碼將是業務邏輯。如果有一件事我想你在閱讀本文之后記住,那就是業務邏輯不需要放在 React 組件中。將業務邏輯用普通 JavaScript 函數和類來實現通常是有意義的。由于沒有一個更好的名字,我將它稱之為控制器

所以只有三種類型的 React 組件。但仍然有四種類型的組件,因為不是每個組件都是一個 React 組件。

并不是每輛車都是豐田(但至少在東京大部分都是)。

控制器通常遵循類似的模式。它們:

  • 存儲某個狀態。
  • 有改變那個狀態的動作,并可能引起副作用。
  • 可能有一些訂閱狀態變更的方法,而這些變更不是由動作直接造成的。
  • 可以接受類似屬性的配置,或者訂閱某個全局控制器的狀態。
  • 依賴于任何 React API。
  • 與 DOM 進行交互,也沒有任何樣式。

你可以從你的組件中拆分出控制器的一些跡象:

  • 組件有很多與部分輸入無關的狀態。
  • 狀態用于存儲從服務器接收到的信息。
  • 引用全局狀態,如拖放或導航的狀態。

一些控制器的示例:

  • 一個 Redux 或者 Flux 的 store。
  • 一個帶有 MobX 可觀察的 JavaScript 類。
  • 一個包含方法和實例變量的普通 JavaScript 類。
  • 一個事件發射器。

一些控制器是全局的;它們完全獨立于你的 React 應用程序。Redux 的 stores 就是一個是全局控制器很好的例子。但并不是所有的控制器都需要是全局的,也并不是所有的狀態都需要放在單獨的控制器或者 store 中。

通過將表單和列表的控制器代碼拆分為單獨的類,你可以根據需要在容器組件中實例化這些類。

容器組件

容器組件是將控制器連接到展示組件和控制組件的粘合劑。它們比其他類型的組件更具有靈活性。但仍然傾向于遵循一些模式,它們:

  • 在組件狀態中存儲控制器實例。
  • 通過展示組件和控制組件來渲染狀態。
  • 使用生命周期方法來訂閱控制器狀態的更新。
  • 使用 DOM 標記或樣式(可能出現的例外是一些無樣式的 div)。
  • 通常由像 Redux 的 connect 這樣的高階函數生成。
  • 可以通過上下文訪問全局控制器(例如 Redux 的 store)。

雖然有時候你可以從其他容器中拆分出容器組件,但這很少見。相反,最好將精力集中在拆分控制器、展示組件和控制組件上,并將剩下的所有都變成你的容器組件。

一些容器組件的示例:

  • 一個 App 組件
  • 由 Redux 的 connect 返回的組件。
  • 由 MobX 的 observer 返回的組件。
  • react-router 的 <Link> 組件(因為它使用上下文并影響環境)。

組件文件

你怎么稱呼一個不是視圖、控制、控制器或容器的組件?你只是把它叫做組件!很簡單,不是嗎?

一旦你拆分出一個組件,問題就變成了我把它放在哪里?老實說,答案很大程度上取決于個人喜好,但有一條規則我認為很重要:

如果拆分出的組件只在一個父級中使用,那么它將與父級在同一個文件中

這是為了盡可能容易地拆分組件。創建文件比較麻煩,并且會打斷你的思路。如果你試著將每個組件放在不同的文件中,你很快就會問自己“我真的需要一個新組件嗎?”因此,請將相關的組件放在同一個文件中。

當然,一旦你找到了重用該組件的地方,你可能希望將它移動到單獨的文件中。這就使得把它放到哪個文件中去成為一個甜蜜的煩惱了。

性能怎么樣?

將一個龐大的組件拆分成多個控制器、展示組件和控制組件,增加了需要運行的代碼總量。這可能會減慢一點點,但不會減慢很多。

故事

我遇到過唯一一次由于使用太多組件而引起性能問題 —— 我在每一幀上渲染 5000 個網格單元格,每個單元格都有多個嵌套組件。

關于 React 性能的是,即使你的應用程序有明顯的延遲,問題肯定不是出于組件太多。

所以你想使用多少組件都可以

如果沒有拆分……

我在本文中提到了很多規則,所以你可能會驚訝地聽到我其實并不喜歡嚴格的規則。它們通常是錯的,至少在某些情況下是這樣。所以必須要明確的是:

『可以』拆分并不意味著『必須』拆分

假設你的目標是讓你的代碼更易于理解和維護,這仍然留下了一個問題:怎樣才是易于理解?怎樣才是易于維護?而答案往往取決于誰在問,這就是為什么重構是技術,更是藝術。

有一個具體的例子,考慮下這個組件的設計:

<!DOCTYPE html> <html><head><title>I'm in a React app!</title></head><body><div id="app"></div><script src="https://unpkg.com/react@15.6.1/dist/react.js"></script><script src="https://unpkg.com/react-dom@15.6.1/dist/react-dom.js"></script><script>// 這里寫 JavaScript</script></body> </html>復制代碼class List extends React.Component {renderItem(item, i) {return (<li key={item.id}>{item.name}</li>)}render() {return (<ul>{this.props.items.map(this.renderItem)}</ul>)} }ReactDOM.render(<List items={[{ id: 'a', name: 'Item 1' },{ id: 'b', name: 'Item 2' }]} />,document.getElementById('app') )復制代碼

盡管將 renderItem 拆分成一個單獨的組件是完全可能的,但這樣做實際上會有什么好處呢?可能沒有。實際上,在具有多個不同組件的文件中,使用 renderItem 方法可能會更容易理解。

請記住:四種類型的組件是當你覺得它們有意義的時候,你可以使用的一種模式。它們并不是硬性規定。如果你不確定某些內容是否需要拆分,那就不要拆分,因為即使某些組件比其他組件更臃腫,世界末日也不會到來。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、React、前端、后端、產品、設計 等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。

轉載于:https://juejin.im/post/59aa7f8c6fb9a024747f13b7

總結

以上是生活随笔為你收集整理的[译] 你是如何拆分组件的?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲免费观看高清 | 亚洲综合中文字幕在线 | 在线免费中文字幕 | 国产精品日韩电影 | 成人免费看片&#39; | 男女精品视频 | 欧美黑吊大战白妞 | 自拍偷拍麻豆 | 国产毛片久久久久久国产毛片 | 四虎色网 | 美女午夜影院 | 波多野结衣视频免费看 | wwwxxx在线播放 | 国产一级在线观看 | 69一区二区 | 国产精品乱码一区二三区小蝌蚪 | 理论片午午伦夜理片影院99 | 欧美巨乳美女 | 久久99热这里只有精品 | 亚洲精品视频久久 | 奇米二区 | 麻豆免费在线 | 日本不卡一区在线观看 | 亚洲国产精品一区二区久久hs | 精品一区二区三区四区五区六区 | 久久精品五月天 | 91麻豆一区二区 | 日韩视频在线观看二区 | 欧美精品免费看 | 成人看的毛片 | 中文在线观看av | 好吊操av| 仙踪林久久久久久久999 | 国产精品交换 | 久久av红桃一区二区小说 | 葵司av在线| 久久久久久国产精品一区 | 91av视频在线免费观看 | 国产欧美日韩三区 | 久久成人免费 | 国内自拍视频在线播放 | 亚州国产 | 欧美日韩黄色一区二区 | 激情综合网婷婷 | 在线观看视频二区 | 蜜桃av一区 | 在线观看日韩av | 播放灌醉水嫩大学生国内精品 | av大全在线观看 | 毛片3| 国产色婷婷 | 老熟妇仑乱一区二区视频 | 中文天堂 | 国产精在线 | 毛片专区 | 少妇一区二区三区 | 午夜在线精品偷拍 | 午夜免费毛片 | 1769国产精品视频 | 国产免费片 | 日本视频精品 | 国产黄色激情视频 | 精品国产99一区二区乱码综合 | 手机成人在线视频 | 欧美成人动态图 | www日本黄色| www成年人 | 丁香婷婷激情五月 | 久久久网 | 中文在线观看免费高清 | 少妇精品久久久久久久久久 | 波多野结衣一区二区三区高清 | 欧美少妇b| 三级黄色网 | 国产91精品一区 | 波多一区二区 | 毛片高清免费 | 精品国产99久久久久久宅男i | 黄色免费在线网站 | 色呦呦麻豆 | 999www| 免费无码国产v片在线观看 三级全黄做爰在线观看 | 国产一区美女 | 自拍视频一区二区 | 毛片大全在线观看 | 欧美激情亚洲激情 | 人妻内射一区二区在线视频 | 激情五月综合 | av香港经典三级级 在线 | 麻豆爱爱视频 | 日本内谢少妇xxxxx少交 | 欧美日韩在线国产 | 特种兵之深入敌后 | 成人av网站大全 | 日本一级二级视频 | 日韩黄色影视 | 国内成人自拍视频 | 美女搞黄视频网站 | 亚洲va久久久噜噜噜无码久久 |