唉,新公司的代码不忍卒读,忍不住记录下个人对于前端代码复用,分离的理解….
- 不要在代码中直接使用请求函数
强烈谴责在每次发起请求的时候写类似这样的代码
1 | componentDidMount(){ |
所有的请求应该单独写在service文件夹下,提供一个语义化的方法如下所示
1
2
3
4
5
6
7
8export const getUserInfo = (id:string):Promise<{name:string,age:number}>=>{
return Request({method:'post',url:'/info',data:{id:'123'}})
}
// 用async也行。
export async function getUserInfo(id:string):{
const result = await Request({method:'post',url:'/info',data:{id:'123'}})
return result
}
好处如下:
- 给接口语义化,在没有注释的情况下不至于抓瞎,特别是如果接口本身不够rest(比如现在公司所有接口都是/123/123这样的数字组成,完全不能根据接口地址来判断这个接口有个啥子用)。
- 复用性强,现在在项目中全局搜索某个接口名三四个地方用到该接口,如果放到service,找到相关调用地点,直接跑到函数定义出find refrence,他不香吗?还可以少写几遍接口名称,或者是相关参数。
- 还是复用强,所有的接口管理得当,可以直接作为一个单独的项目发布,给所有的业务项目提供底层依赖,而service项目可以编写相关单测脚本,定时去跑测试代码,监控接口的状态。
- React 代码分层
当一个功能人家说做过了可复用,结果我发现这个功能杂糅在一个七八百行的jsx内要复用就得自己拆出来的时候,我的内心是崩溃的。
写一个功能多的展示活动页(活动页为什么没有活动页面的素材组件啊!!!!),个人建议将组件用api影响范围分为多个container。
比如首页的banner,必定是访问一个获取banner数据的api然后将api返回的内容放到banner。这个时候建议将这个api分离出一个banner container,container包含了获取api数据,和render banner的功能。
如果这个banner可能其它地方用到呢,就将里面的视图相关的内容再拆出来拆成一个component。在其它地方就可以访问api然后直接return <Banner {…data}/>就好了。
那么当其它页面也要用到,并且连接口都是相同的,只是参数换了下嘞。建议将接口相关内容做成高阶函数,通过props注入的方式去组合高阶函数和Component(高阶函数可以复用setState相关的逻辑,不只是props注入,各种逻辑复用都可以考虑用高阶,当然现在有了hook,如果用hook逻辑复用第一考虑的一定是自定义hook啦)
1 | import React from 'react' |
- 使用状态管理
要做到更好的复用,但是hoc和分组件当然是不够用啊,首页要用某个api的数据,用户主页也需要用某个api的数据,最好的设计当然是,只需要请求一次接口,然后将数据保存在本地,其它页面就那本地存储即可。
用什么呢,localStorage sessionStorage,indexDB,web SQL?不行,单纯只是为了本地存储无法做出有效的管理,阅读代码的时候永远不知道这个storage从哪里来,为了什么,什么时候该清除(我是谁,我从哪里来,我要去哪里既视感)。
状态管理就是为了解决这些个问题。维护一颗状态树,所有需要复用的数据存在状态树中,随用随取,用的数据不同时,搞一个子树作为存储,提供相应的更新的函数即可。妈的简直不要太好用好吗。
当然有同事说,之前碰到过状态树过大,不好维护,这里建议树太大的时候拆模块呢,直接将各种子树拆成子模块,在加载的时候提供获取基础数据的方式(可以是api,可以是本地存储,办法总比困难多)
公司所有项目有Dva的依赖,但是真的用的地方少的可怜….真的强烈建议还是用一下。