欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

react?hooks?UI與業(yè)務(wù)邏輯分離必要性技術(shù)方案

 更新時(shí)間:2022年11月10日 10:24:06   作者:trigkit4  
這篇文章主要為大家介紹了react?hooks?UI與業(yè)務(wù)邏輯分離必要性技術(shù)方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

當(dāng)前端業(yè)務(wù)復(fù)雜度上升到一定程度的時(shí)候,如何提升前端代碼質(zhì)量便成了老生常談的話題。似乎前端總逃不開(kāi)改他人代碼,重構(gòu),修復(fù)bug的宿命。那么,我們要如何從項(xiàng)目代碼層面,改變這一局面呢?才能保證項(xiàng)目A之于開(kāi)發(fā)者B也是能有條不紊的介入開(kāi)發(fā),從而最大程度降低人員開(kāi)銷,實(shí)現(xiàn)真正降本提效呢?

從代碼層面的問(wèn)題上看,我列舉了下,大概有如下幾種:

  • 工程化沒(méi)有做好各類lint檢查和約束

超長(zhǎng)的function

  • 很難單從函數(shù)名看出這個(gè)函數(shù)是作什么的
  • 一個(gè)函數(shù)做了十件事

代碼量超長(zhǎng)的模塊

  • 內(nèi)部維護(hù)了非常多邏輯,很難一眼看清某個(gè)變量是在哪里被修改的
  • 一個(gè)組件夾雜了這個(gè)組件所需的所有代碼,不懂職責(zé)劃分的重要性

缺乏清晰的職責(zé)劃分

  • 哪個(gè)模塊做什么,對(duì)于數(shù)據(jù)應(yīng)該如何流向,如何改變沒(méi)有清晰的認(rèn)知

數(shù)據(jù)流紊亂

  • 缺乏函數(shù)式寫(xiě)法的意識(shí)

變量命名極不規(guī)范

  • 變量命名很含糊,能通過(guò)命名講清楚這個(gè)函數(shù)是做什么的,卻很隨意對(duì)待

檢驗(yàn)好代碼的唯一標(biāo)準(zhǔn)應(yīng)該是:人們能否輕而易舉地修改它

業(yè)務(wù)的問(wèn)題

我們知道,業(yè)務(wù)迭代往往排山倒海壓來(lái),一開(kāi)始如果不做好全局規(guī)劃,或者理清各個(gè)模塊的關(guān)系,是很難把控好進(jìn)度,進(jìn)而出現(xiàn)趕工導(dǎo)致bug滋生。那么,目前的hooks 業(yè)務(wù)組件的寫(xiě)法有何問(wèn)題呢?

基于hooks的純業(yè)務(wù)組件寫(xiě)法沒(méi)有做約束,ui與業(yè)務(wù)邏輯在一個(gè)函數(shù)內(nèi)部維護(hù),面條式代碼滋生,容易使組件業(yè)務(wù)邏輯代碼越寫(xiě)越長(zhǎng),久而久之難以維護(hù)。很容易出現(xiàn)一個(gè)函數(shù)內(nèi)部耦合了types,constants,各類hooks(useState,useReducer,useCallback等),以及各種function,甚至是在dom層夾雜著非常多的邏輯處理。

慢慢地,復(fù)用性也會(huì)越來(lái)越差,可能需要經(jīng)常重構(gòu),抽離代碼 以達(dá)到復(fù)用的程度。但往往業(yè)務(wù)的排期已經(jīng)沒(méi)法抽開(kāi)身去維護(hù)老代碼,那怎么辦呢?

hooks組件的分離

《重構(gòu)2:改善既有代碼的設(shè)計(jì)》一文提到:把復(fù)雜的代碼塊分解為更小的單元,與好的命名一樣都很重要。

因此,我們需要在團(tuán)隊(duì)內(nèi)部達(dá)成共識(shí),能夠產(chǎn)出一種固定的開(kāi)發(fā)范式,能夠分離代碼,做到職責(zé)清晰,例如:A模塊專門(mén)處理View視圖組件,B模塊專門(mén)處理業(yè)務(wù)邏輯,C模塊專門(mén)維護(hù)ts類型types,D模塊專門(mén)維護(hù)各類常量constants,E模塊專門(mén)維護(hù)公用hooks邏輯,F(xiàn)模塊專門(mén)維護(hù)css modules等。

那么,在這前提之下,我們需要實(shí)現(xiàn)前端UI與業(yè)務(wù)邏輯分離,目前主流的有兩種方式,一種是純邏輯抽離出去,返回函數(shù)內(nèi)部方法和state;形如:

const useApp = () => {
   const [name, setName] = useState('mike');
   const getName = () => {};
   const updateName = () => {};
   return {
      name,
      getName,
      updateName
   }
}
const AppView =() => {
 const { name } = useApp();
 return <div>{name}</div>
}

這種方式?jīng)]什么太大問(wèn)題,但這種代碼不內(nèi)聚,沒(méi)法提供通用的邏輯處理,一旦業(yè)務(wù)發(fā)生變化,就會(huì)引發(fā)多處代碼的維護(hù)危機(jī)。
其次如果有很多業(yè)務(wù)團(tuán)隊(duì),那么就需要考慮如何規(guī)范化統(tǒng)一團(tuán)隊(duì)內(nèi)部寫(xiě)法,如何支持更健壯的業(yè)務(wù)代碼。
UI與邏輯分離并不是最終的目的,最終的目的應(yīng)該是形成一套易于維護(hù),模塊職責(zé)劃分清晰,能夠形成固定開(kāi)發(fā)模式,易于擴(kuò)展,能夠規(guī)范化業(yè)務(wù)使用場(chǎng)景,且具備強(qiáng)壯生命力的方案。

如果這種方式可以實(shí)現(xiàn)的話,那么為何很少有人會(huì)這么干呢?原因可能在于大家的函數(shù)式組件的思維。

在hooks還沒(méi)誕生之前,大家普遍對(duì)于函數(shù)式組件的認(rèn)知就是沒(méi)有state,所以當(dāng)props是固定的,那么函數(shù)式組件每次渲染結(jié)果也都是一樣的,也就是相同的輸入總能得到相同的輸出。但現(xiàn)在hooks出現(xiàn)了,函數(shù)組件內(nèi)部可以維護(hù)state了,相同的輸入并不一定能得到相同的輸出了。

此外,這種方式與可復(fù)用的hooks的區(qū)別又在哪里,如果兩種都使用hooks維護(hù),又如何區(qū)分呢?

另外一種方式就是保留業(yè)務(wù)邏輯,但把UI組件抽離出去,這種方式更不推薦了。有點(diǎn)類似子組件,父子組件通信的既視感隨之襲來(lái)。

接下來(lái),我們?cè)賮?lái)看下純hooks組件飽受大家詬病的一些問(wèn)題:

純hooks組件的問(wèn)題

1、useState 寫(xiě)法難用,如果有很多state,需要一個(gè)個(gè)去維護(hù),寫(xiě)法不夠簡(jiǎn)潔;當(dāng)業(yè)務(wù)邏輯越來(lái)越復(fù)雜,往往會(huì)出現(xiàn)一個(gè)模塊幾十個(gè)useState需要維護(hù)的尷尬局面。

2、useReducer + context的全局狀態(tài)難用,仍然需要定義很多action type,還需要提供provider,使用useReducer跨組件共享狀態(tài)很麻煩

3、useCallback 用法不夠清晰,不知何時(shí)用何時(shí)不用,用法造成困惑

4、 生命周期需要引入useEffect,需要手動(dòng)管理,且不夠語(yǔ)義化

5、基于hooks的業(yè)務(wù)組件,內(nèi)部方法依然難以做到復(fù)用,應(yīng)抽離出去單獨(dú)維護(hù)。

6、當(dāng)使用useEffect模擬mounted事件時(shí),處理異步請(qǐng)求函數(shù)時(shí)很麻煩。

7、當(dāng)組件達(dá)到一定復(fù)雜度的時(shí)候,堆積到一起的代碼會(huì)變得越來(lái)越難以維護(hù)

8、React Hook的閉包陷阱問(wèn)題

9、useState 調(diào)用updater更新后,無(wú)法同步獲取最新state值

10、useState updater無(wú)法實(shí)現(xiàn)細(xì)粒度更新對(duì)象的屬性值,不得不淺拷貝一份數(shù)據(jù)再進(jìn)行覆蓋

hooks-view-model

想要寫(xiě)出健壯的,長(zhǎng)期可持續(xù)維護(hù)的代碼,就必須去理解這些在其他編程領(lǐng)域通用的設(shè)計(jì)模式、原則、范式。提高代碼質(zhì)量,除了依賴開(kāi)發(fā)自測(cè)和相關(guān)流程規(guī)范化外,也應(yīng)有相關(guān)工具或統(tǒng)一的開(kāi)發(fā)范式做約束。

對(duì)于純寫(xiě)業(yè)務(wù)的人來(lái)說(shuō),沒(méi)有規(guī)范去強(qiáng)制約定,那么幾乎沒(méi)有人會(huì)這么處理業(yè)務(wù)邏輯與UI的關(guān)系,最終還是會(huì)寫(xiě)到一起。這是hooks這種弱約束的弊端。

基于上述問(wèn)題,我開(kāi)發(fā)了基于react hooks的UI與業(yè)務(wù)邏輯分離的方案,內(nèi)部基于useState hooks的updater 實(shí)現(xiàn)。可實(shí)現(xiàn)在class內(nèi)部setState,然后在View組件中響應(yīng)更新。基本解決了上述react hooks的十個(gè)“老大難”問(wèn)題

hooks-view-model是一種通過(guò)拆分UI視圖與業(yè)務(wù)邏輯的解決方案,可做到無(wú)需useReducer,無(wú)需redux等技術(shù)方案實(shí)現(xiàn)全局狀態(tài)更新而不會(huì)渲染無(wú)關(guān)組件。hooks-view-model是集狀態(tài)管理,變量的存儲(chǔ)管理和數(shù)據(jù)的持久化管理于一體的解決方案。

詳情點(diǎn)擊??:https://github.com/hawx1993/h...

hooks-view-model 主要用于分離UI與業(yè)務(wù)邏輯,可以解決 純hooks組件的問(wèn)題,對(duì)比一下hooks-view-model的優(yōu)勢(shì):

hooks組件問(wèn)題hooks-view-model
useState 寫(xiě)法難用,如果有很多state,需要一個(gè)個(gè)去維護(hù),寫(xiě)法不夠簡(jiǎn)潔可通過(guò)對(duì)象形式更新與解構(gòu)數(shù)據(jù),寫(xiě)法簡(jiǎn)潔
useReducer + context的全局狀態(tài)難用,仍然需要定義很多action type,還需要提供provider,使用useReducer跨組件共享狀態(tài)很麻煩全局狀態(tài)更新只需使用useGlobalStatehooks,用法簡(jiǎn)單
生命周期需要引入useEffect,需要手動(dòng)管理,且不夠語(yǔ)義化提供mounted和unmounted 鉤子函數(shù),可自動(dòng)執(zhí)行,語(yǔ)義化友好
基于hooks的業(yè)務(wù)組件,內(nèi)部方法依然難以做到復(fù)用,應(yīng)抽離出去單獨(dú)維護(hù)class 寫(xiě)法可通過(guò)繼承 實(shí)現(xiàn)復(fù)用,還可以通過(guò)useVM引入其他viewModel進(jìn)行復(fù)用,復(fù)用性高
當(dāng)接收新的props,需要手動(dòng)使用useEffect觀察props變化,沒(méi)有直接的鉤子可以自動(dòng)觸發(fā)class 提供onPropsChanged 鉤子函數(shù),可自動(dòng)觸發(fā)執(zhí)行
當(dāng)組件達(dá)到一定復(fù)雜度的時(shí)候,堆積到一起的代碼會(huì)變得越來(lái)越難以維護(hù)UI與邏輯做到了很好的分離,代碼組織性強(qiáng)
React Hook的閉包陷阱問(wèn)題由于方法都提到class中去維護(hù)了,所以不存在此問(wèn)題
useState 調(diào)用updater更新后,無(wú)法同步獲取最新state值可通過(guò)調(diào)用getCurrentState 同步獲取最新值
調(diào)用updater無(wú)法實(shí)現(xiàn)細(xì)粒度更新對(duì)象屬性值,需淺拷貝對(duì)象后覆蓋可通過(guò)updateImmerState實(shí)現(xiàn)細(xì)粒度更新

1、View:獲取數(shù)據(jù)并展示數(shù)據(jù)

// AppView.tsx
import { AppViewModel } from './AppViewModel'
import { useVM } from 'hooks-view-model'
import { usePrevious } from '@/hooks';
const AppView = () => {
  const { perviousAddress } = usePrevious();
  const { changeAddress, useCurrentState } = useVM(AppViewModel, {
    address: perviousAddress,
  })
  const { address = 'ZheJiang Province' } = useCurrentState()
  return (
    <div>
      <button onClick={changeAddress}>click to change address</button>
      <span>{address}</span>
    </div>
  )
}

2、ViewModel:管理狀態(tài)和處理數(shù)據(jù)

updateGlobalStateByKey 和 updateCurrentState 相當(dāng)于在class中可以使用的setState方法,只不過(guò)需要保證class中的所有方法都是箭頭函數(shù),否則會(huì)報(bào)錯(cuò)

// AppViewModel.ts
import  StoreViewModel from 'hooks-view-model'
class AppViewModel extends StoreViewModel {
  changeAddress = () => {
    this.updateCurrentState(this.props.address);// 相當(dāng)于setState
  }
}
export { AppViewModel }

那么可能有很多人就疑惑了,明明react官方已經(jīng)推崇函數(shù)式寫(xiě)法了,為什么還要用class?

基于class的viewModel寫(xiě)法與hooks有什么區(qū)別

誠(chéng)然,hooks 可滿足UI與邏輯分離的需求,但抽離無(wú)法被公用的業(yè)務(wù)邏輯到hooks中是否有必要?與可復(fù)用的hooks 是否容易造成混淆?hooks存在的useCallback,useReducer,以及對(duì)副作用的使用等容易造成使用困惑的,以及對(duì)useState 使用上的麻煩是否可以有其他方法簡(jiǎn)化?

其次,函數(shù)式組件的寫(xiě)法也并非函數(shù)式編程,相同的輸入(props)并不會(huì)得到相同的輸出(內(nèi)部的state或全局的state都可能對(duì)結(jié)果產(chǎn)生影響)。

而業(yè)務(wù)邏輯抽離到class中,依然是函數(shù)式組件。class相比于function 天然的具有可組織性,可擴(kuò)展性(extends),和可維護(hù)性。

首先,業(yè)務(wù)邏輯是比較復(fù)雜的,Class 具備繼承能力,可實(shí)現(xiàn)viewModel與view都獲得來(lái)自父類的能力;

其次,class 能夠更好維護(hù)業(yè)務(wù)邏輯代碼,在class中寫(xiě)業(yè)務(wù)邏輯,完全可以忽視r(shí)eact hooks自帶的各種hooks,諸如useRef,useCallback,useReducer,useState等,寫(xiě)起業(yè)務(wù)邏輯來(lái)更加純粹;

再者,hooks 也可以與viewModel共存,只需要在view中引入hooks,然后將返回值作為props,通過(guò)useVM傳給viewModel即可,兩者是共存的,并不是互斥的。

基于class的viewModel可以更好的維護(hù)業(yè)務(wù)邏輯代碼,可以使用裝飾器,public,private等關(guān)鍵字,顯示提高代碼可維護(hù)性和擴(kuò)展能力。而可復(fù)用的hooks可以用來(lái)抽象業(yè)務(wù)邏輯實(shí)現(xiàn)副作用觀察和邏輯復(fù)用,兩者具有不同的心智模型。

配置生成項(xiàng)目模板文件

此外,我還在hooks-view-model內(nèi)置了項(xiàng)目的模板文件,可一鍵生成所需模板文件和代碼,這樣便可以讓各個(gè)業(yè)務(wù)線的前端團(tuán)隊(duì)始終保持一致的開(kāi)發(fā)規(guī)范和風(fēng)格。

可以真正做到成員B可以低成本介入項(xiàng)目A中,提高代碼的可維護(hù)性,可閱讀性。用法如下:

執(zhí)行如下步驟,可一鍵生成模板文件

1、添加腳本命令

在package.json的scripts中添加如下腳本命令

scripts: {
  "generate": "plop --plopfile ./node_modules/hooks-view-model/generators/index.js"
}

2、根目錄創(chuàng)建template.config.js

指明模板需要生成的相對(duì)路徑地址:

const dir_to_generate = './src/pages/';
module.exports = dir_to_generate;

執(zhí)行完后,便會(huì)在指定的目錄下生成如下模板文件:

更好的debug能力

使用hooks,我們?nèi)绻胫喇?dāng)前的state值,我們需要一個(gè)個(gè)console出來(lái),而基于hooks-view-model,我們只需要在控制臺(tái)輸入:globalStore,即可查看所有view對(duì)應(yīng)的state,通過(guò)key區(qū)分??纱蟠筇嵘齞ebug能力。

以上就是react hooks UI與業(yè)務(wù)邏輯分離必要性技術(shù)方案的詳細(xì)內(nèi)容,更多關(guān)于react hooks UI業(yè)務(wù)邏輯分離的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • react項(xiàng)目實(shí)踐之webpack-dev-serve

    react項(xiàng)目實(shí)踐之webpack-dev-serve

    這篇文章主要介紹了react項(xiàng)目實(shí)踐之webpack-dev-serve,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • React之錯(cuò)誤邊界 Error Boundaries示例詳解

    React之錯(cuò)誤邊界 Error Boundaries示例詳解

    這篇文章主要為大家介紹了React之錯(cuò)誤邊界Error Boundaries示例教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • react在安卓中輸入框被手機(jī)鍵盤(pán)遮擋問(wèn)題的解決方法

    react在安卓中輸入框被手機(jī)鍵盤(pán)遮擋問(wèn)題的解決方法

    這篇文章主要給大家介紹了關(guān)于react在安卓中輸入框被手機(jī)鍵盤(pán)遮擋問(wèn)題的解決方法,文中通過(guò)圖文以及示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧
    2018-09-09
  • 用React實(shí)現(xiàn)一個(gè)簡(jiǎn)單的虛擬列表

    用React實(shí)現(xiàn)一個(gè)簡(jiǎn)單的虛擬列表

    虛擬列表是現(xiàn)在比較常用的前端渲染大數(shù)據(jù)列表的方案,目前也有很多組件庫(kù)和工具庫(kù)也都有對(duì)應(yīng)的實(shí)現(xiàn),本文將給大家介紹一下如何用React實(shí)現(xiàn)一個(gè)簡(jiǎn)單的虛擬列表,文中通過(guò)代碼示例講解的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • 詳解React Native頂|底部導(dǎo)航使用小技巧

    詳解React Native頂|底部導(dǎo)航使用小技巧

    本篇文章主要介紹了詳解React Native頂|底部導(dǎo)航使用小技巧 ,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • React 使用browserHistory項(xiàng)目訪問(wèn)404問(wèn)題解決

    React 使用browserHistory項(xiàng)目訪問(wèn)404問(wèn)題解決

    這篇文章主要介紹了React 使用browserHistory項(xiàng)目訪問(wèn)404問(wèn)題解決,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • 關(guān)于react+antd樣式不生效問(wèn)題的解決方式

    關(guān)于react+antd樣式不生效問(wèn)題的解決方式

    最近本人在使用Antd開(kāi)發(fā)時(shí)遇到些問(wèn)題,所以下面這篇文章主要給大家介紹了關(guān)于react+antd樣式不生效問(wèn)題的解決方式,文中通過(guò)圖文以及實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • React中使用Axios發(fā)起POST請(qǐng)求提交文件方式

    React中使用Axios發(fā)起POST請(qǐng)求提交文件方式

    這篇文章主要介紹了React中使用Axios發(fā)起POST請(qǐng)求提交文件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • React中setState更新?tīng)顟B(tài)的兩種寫(xiě)法

    React中setState更新?tīng)顟B(tài)的兩種寫(xiě)法

    在?React?中,我們經(jīng)常需要更新組件的狀態(tài)(state),使用?setState?方法是一種常見(jiàn)的方式來(lái)實(shí)現(xiàn)狀態(tài)的更新,而在使用?setState?方法時(shí),有兩種不同的寫(xiě)法,即對(duì)象式和函數(shù)式,本文將介紹這兩種寫(xiě)法的區(qū)別和使用場(chǎng)景,需要的朋友可以參考下
    2024-03-03
  • 基于react封裝一個(gè)通用可編輯組件

    基于react封裝一個(gè)通用可編輯組件

    前段時(shí)間接到這樣一個(gè)需求,需要封裝一個(gè)組件實(shí)現(xiàn)可編輯,這個(gè)到底有多通用呢,就是需要在普通的文字展示包括表格,列表等等,所以本文將給大家介紹如何基于react封裝一個(gè)通用可編輯組件,需要的朋友可以參考下
    2024-02-02

最新評(píng)論