本文须要要求读者由 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 私聊~
工做地点基本涵盖全国各大一线城市,欢迎您的到来呀