本文須要要求讀者由 typescript 和 react 的相關知識才能理解!前端
若是在業務中遇到代碼難梳理,邏輯錯綜複雜,維護性不高的狀況,能夠繼續讀一讀,瞧一瞧react
在我業務中遇到過對複雜結構的數據修改,例如如今有一個數據結構以下(這些都是真實地業務中脫敏出來的)typescript
interface complexData {
complexDataUniqueId: string; // 複雜數據結構的 惟一id
relatedDatas: OtherComplexData[];
...otherUnconsideredInfos; // 其餘和本文無關的數據
}
interface OtherComplexData {
otherComplexDataUniqueId: string; // 複雜數據結構2的 惟一id
user_info: userInfo;
...otherUnconsideredInfos; // 其餘和本文無關的數據
}
interface userInfo {
user_id: string;
user_name: string;
age: number;
user_follow_info: userFollowInfo;
...otherUnconsideredInfos; // 其餘和本文無關的數據
}
interface userFollowInfo {
relation_type: RelationType;
...otherUnconsideredInfos; // 其餘和本文無關的數據
}
enum RelationType {
// 互不關注
NON_FOLLOW = 0,
// 已關注
FOLLOWED = 1,
// 被關注
FOLLOWING = 2,
// 互相關注
MUTUAL_FOLLOWING = 3
}
複製代碼
如上所示數據結構至關之複雜,一個複雜的數據結構中包含了另一個複雜的數據結構,另一種複雜的數據結構中包含了用戶的信息,用戶的信息中包含了該用戶和當前登陸用戶的關係數組
而後在如今業務上需求是,由一個 complexData[] 的數組,輸入一個 otherComplexDataUniqueId 匹配到其對應的關聯的數據,而後修改這個結構的用戶關係(好比 從 互不關注 變成 已關注)微信
按照面向過程的思考方式,咱們能夠很快的寫出一段僞代碼markdown
state = {
complexDatas: [complexData, complexData, complexData, ...]
}
followSomeUser (targetId: string) {
// 也許就在你的業務代碼中也會像我同樣,充斥着大量大段大段的相似這樣的函數
// 邏輯錯綜複雜,功能難以維護
this.setState({
complexDatas: complexDatas.map(item => {
item.relatedDatas.map(cItem => {
if (targetId === cItem.otherComplexDataUniqueId) {
cItem = {
...cItem,
cItem.user_info = {
...cItem.user_info,
user_follow_info: {
...cItem.user_info.user_follow_info,
relation_type: RelationType.FOLLOWED // 修改爲已經關注
}
}
}
}
})
})
})
}
複製代碼
思路很清晰,保持全部其餘的數據不變,並返回新的引用(react) 可是這樣寫實在是很是的複雜醜陋,讓人摸不清邏輯,做者可能沒幾個月後也會忘記數據結構
因此,咱們在寫業務代碼中,須要能夠很好的把代碼邏輯拆分,下面讓咱們來簡單把上述的僞代碼作一個拆分和解構ide
咱們把代碼分紅兩個部分,查找 和 賦值函數
首先是查找,咱們能夠把查找抽象成一個函數來作ui
// 函數式的查找須要修改的目標, 匹配目標id
const match = (o: otherComplexData, targetId: string) => o.otherComplexDataUniqueId === targetId;
複製代碼
// 賦值(對於數據結構的更新,和更新補丁相似,因此叫patch)
const patchOtherComplexDataFollowRelation = (o: otherComplexData, relation_type: RelationType) => {
return {
...o,
o.user_info = {
...o.user_info,
user_follow_info: {
...o.user_info.user_follow_info,
relation_type // 修改爲已經關注
}
}
}
}
複製代碼
而後是遍歷並修改
const updateList = (list: complexData[], targetId: string) => {
return list.map(item => item.relatedDatas.map(cItem => { match(cItem, targetId) ? ...patchOtherComplexDataFollowRelation(cItem, RelationType.FOLLOWED) : cItem} ))
}
複製代碼
讓咱們完整地看看用函數式 + 解耦的方式寫
state = {
complexDatas: [complexData, complexData, complexData, ...]
}
followSomeUser (targetId: string) {
const match = (o: otherComplexData, targetId: string) => o.otherComplexDataUniqueId === targetId;
const patchOtherComplexDataFollowRelation = (o: otherComplexData, relation_type: RelationType) => {
return {
...o,
o.user_info = {
...o.user_info,
user_follow_info: {
...o.user_info.user_follow_info,
relation_type // 修改爲已經關注
}
}
}
}
const updateList = (list: complexData[], targetId: string) => {
return list.map(item => item.relatedDatas.map(cItem => { match(cItem, targetId) ? ...patchOtherComplexDataFollowRelation(cItem, RelationType.FOLLOWED) : cItem} ))
}
// 這樣看起來是否是很是的清晰,讓人易於理解?
this.setState(s => ({ complexDatas: updateList(s.complexDatas) }))
}
複製代碼
經過兩種方式的比較,咱們能夠明確認識到,當咱們平時業務中遇到一大段很是複雜的邏輯的時候,必定要學會梳理脈絡 把複雜的邏輯多解耦,該拆分拆分,這樣才能讓咱們寫的代碼更具有更好的可讀性和可維護性
廣告
字節跳動IES招前端啦,有興趣有能力的同窗能夠加我微信:L_star07 私聊~
工做地點基本涵蓋全國各大一線城市,歡迎您的到來呀