如何寫好業務代碼?
在前端工做中有不少業務性代碼,若是書寫不規範,那麼對後期的維護將是很是致命的。html
後端數據庫中常常會一個字段具有幾個不一樣的狀態,好比:前端
status: 2 // 各個字段對應的含義 0: 出生 1: 兒童 2: 少年 3: 中年 4: 老年
下面這段代碼就是常見的無限if/else或者switch場景react
// 業務代碼 switch (status) { case 0: // do something return '出生'; case 1: // do something return '兒童'; ... ... default: return ''; }
這樣作是很差的,由於若是後端再加了一個字段,好比git
5: 已死亡
那麼前端須要從新修改switch函數,這樣須要去修改對應的業務函數,無疑破壞了業務代碼的完整性。github
// cfg.js export const cfg = new Map([ [0, 出生], [1, 兒童], [2, 少年], ... ... ]); // 業務代碼 cfg.get(status)
可是這樣僅僅是顯示相關的狀態,若是涉及到狀態的判斷,那這樣的處理方式就有些問題了,好比須要根據具體的狀態去作對應的判斷數據庫
switch (status) { case 0: // do something return ; ... ... }
像上面的狀況,又變成了第一種狀況,顯然這種配置化的方式並不能知足。若是將對應的操做,與配置分割,則代碼更加不易維護。後端
將狀態處理集中起來,若是能將狀態展現和對應的狀態封裝起來,那麼就會讓後期代碼維護顯得十分集中。app
// cfg.js const status = new Map([ [0, 出生], [1, 兒童], [2, 少年], ... ... ]); const checkIsBirth = (status, callback) => { if(status === 0) { callback && callback() } } export default { status, checkIsBirth } // 在具體使用中 import Person from './cfg.js' const a = 1; Person.status.get(a); Person.checkIsBirth(a, () => { console.log('Person is in Birth state'); })
這樣處理,若是之後status發生變化,只須要修改checkIsBirth中的判斷邏輯就能夠,只須要改動一處。函數
在使用react編寫代碼的過程當中,常常用到這樣的狀況,根據狀況判斷是否展現對應的組件。性能
function Business({status, bug}) { return ( <Fragment> { status === 0 ? ( <div>123</div> ) : null } { bug === 1 ? ( <div>456</div> ) : null } </Fragment> ); }
這樣的寫法若是僅僅只有一個其實還好,若是有不少個,在代碼中會形成代碼很是冗長,使假想一個頁面中若是有不少這樣的,代碼看起來很是ugly。因此建議將代碼分割開來,造成一個個小的組件,將對應的代碼封裝起來,將會使代碼可讀性提升一些。
function Business() { return ( <Fragment> <One isShow={status === 0} /> <One isShow={bug === 1} /> </Fragment> ); } // One function One({isShow}) { return ( <Fragment> { isShow === true ? ( <div>123</div> ) : null } </Fragment> ); } // Two function Two({isShow}) { return ( <Fragment> { isShow === true ? ( <div>456</div> ) : null } </Fragment> ); }
若是常常這麼寫是否是會以爲很煩,能夠將通用的邏輯抽象爲通用的組件。
其實能夠觀望一下decorator之後的用法,暫時沒有找到使用的切入點。
function IsShowCom(isShow, Wrapped) { if (isShow === true) { return (Wrapped) => <Wrapped /> } return () => null; } // 若是你想轉發ref,你得這麼作 function IsShowCom(isShow, Wrapped) { if (isShow === true) { return React.forwardRef((props, ref) => { return <Wrapped {...props} ref={ref} /> }); } return () => null; } // import IsShowCom from './isShowCom'; function Business() { const One = IsShowCom( status === 0, <div> 123 </div> ); const Two = IsShowCom( bug === 1, <div> 456 </div> ); return ( <Fragment> <One/> <Two/> </Fragment> ); }
不要在render中使用高階組件,由於高階組件每次返回來的都是新的組件,會使子組件的狀態丟失 。可是在無狀態組件中,這樣使用並無什麼問題,由於無狀態組件自己就是隨參數的變化而變化的,只是可能會產生性能問題。
前端配置化的總體思路: