【全球热闻】在前端开发工作中,一些微小但对代码提升巨大的点的总结
2022-08-30 16:44:08来源:稀土掘金
我从蚂蚁外包。跳到了字节跳动的外包(实在是进不去字节自研,我就是个菜鸡),虽然我简历上是写的两年半工作经验。但实际从培训班出来也就半年,去年年底来到杭州。在蚂蚁外包干了7个月,枯燥无味的生活促使我跳槽。
其实现在这个大环境(今天2022年8月1日),互联网行业并不好过。阿里裁员40%,字节招人名额减少,跳槽其实并不是一个明智之举。但我还是跳了,因为在蚂蚁外包是在太无聊了,基本上学不到东西,因为没人管你。虽然工资没涨,我也觉得可以了。毕竟自己其实只干了半年多一两个月,有什么资格要求涨工资呢,还是在环境不好的情况下,能找到工作就不错了。
(资料图片仅供参考)
进入字节这边。干的第一个需求,在进行code review的时候,就发现了自己在写代码的时候挺多不足的,也不是说某些地方不会写。就是代码写的好与不好的情况,代码的维护性和可读性上,并不是很好。所以特意来写一篇文章(也是因为需求干完了,是在太无聊了,旁边大佬都看着,只能敲敲键盘):
记录自己代码开发中,一些可以提高的点便于以后自己查阅分享给初入前端的小白们1. 巧用截取数组的方法渲染页面在我的需求中,需要渲染一个描述列表,代码如下,在这个需求里面,我需要动态判断客户是否有名字,来决定是否渲染名字。如果按下面这样写的话,我只需要判断下:
import { Descriptions, Tag } from "antd";import React from "react";// 假设只是用户返回的数据const user = { haveName: true, name: "张xx", live: "浙江杭州", remark: "",}const App: React.FC = () => ();export default App; { user.haveName && {user.haveName} {user.name} }{user.live} {user.remark}
但是这种写法,如果描述列表展示信息少的话,还好。如果描述列表信息多了以后,这个组件看起来其实是不太方便的。并且,描述列表里如果要展示标签,链接,table啥的。这个组件看起来就会更累。所以我把具体的列表信息抽离了出来,这样让组件可读性和维护性上得到提升。具体如下:
// descList.jsexport const descList = [ { key: "haveName", value: "是否有名字", render(val) { return{val} } }, { key: "name", value: "名字" }, { key: "name", value: "地址" }, { key: "name", value: "个性签名", render(val) { return val ? val : "该用户暂未填写个人签名" } },]// index.tsximport { descList } from "./descList.js"import { Descriptions } from "antd";import React from "react";// 假设只是用户返回的数据const user = { haveName: true, name: "张xx", live: "浙江杭州", remark: "123",}const App: React.FC = () => { const desc = useMemo(()=>{ const copyDesc = [...descList] if(obj.haveName) { copyDesc.splice(1,1) } return copyDesc },[obj]) return ({desc.map((item)=> ( )};export default App;{item.render ? item.render(user[item.key]) : user[item.key]} ))}
通过这样改写,我就能通过只改写descList文件,去修改展示的描述列表。从而不去动index里面的逻辑代码。但是细心的小伙伴应该发现了,这样写的话,我没法去判断haveName这个字段,只能通过splice去截取或者filter过滤(这里只展示splice方法的问题)。splice在这里其实有个问题。
从可读性上来说,你后面某位同事改代码,第一眼并不知道去除的哪个元素,从维护性上来说,改了descList列表的话,如果没改index那个截取的序列号,就会导致页面展示的信息错误。所以这里我们需要去改写一下:
const desc = useMemo(()=>{ const copyDesc = [...descList] if(obj.haveName) { copyDesc.splice(copyDesc.findIndex((e=>e.key === "name")),1) } return copyDesc },[obj])
通过上面改写,这样不论如何 都是截取的展示name那一项。
2. 去除项目中的magic数字在step组件中,通常会有很多节点。我们需要根据后端返回的数据来返回一个status来提供他的当前信息。
// 假设后端给我们返回的数据// passed 为0 代表拒绝 1代表已完成 2代表为开始const nodes = [ { key: "开始", passed: 1 }, { key: "人工审批", passed: 0 }, { key: "结束", passed: 2 },]const App: React.FC = () => { const getStatus = (passed) => { if(passed === 0) { return "error" } else if(passed === 1 ) { return "finish" } else if(passed === 2 ) { return "process" } } return ({nodes.map((item)=> )};)}
上面我们判断passed 来返回对应的节点状态。但是不是自己写的功能的话,这个0,1,2几个数字,别人看不懂的。在代码里我们称为魔术数字,所以我们需要改写一下:
// 定义一个映射关系const NodePassMap = new Map([\[0, "error],[1, "finish"],[2, "process"],]);// 获取状态的函数就可以直接改为const getStatus = (passed) => NodePassMap.get(node.Passed);console.log(getStatus(0)) // "error"3. 提供枚举文件说明数字含义
还是上面这个例子,但是有换了个场景,我们需要在passed为0的时候,展示一个特殊的icon:
// 假设后端给我们返回的数据// passed 为0 代表拒绝 1代表已完成 2代表为开始const nodes = [ { key: "开始", passed: 1 }, { key: "人工审批", passed: 0 }, { key: "结束", passed: 2 },]const App: React.FC = () => { const getIcon = (passed) => { if(passed === 0) { return { icon :} } return {} } return ( {nodes.map((item)=> )};)}
上面代码者 这个if判断这里 其实0的含义我们是不知道的,只能通过去询问后端或看之前代码。但是如果我们加一个枚举文件,就能很好的解决这个问题:
type NodePassed = { error: 0, finish: 1, process: 2}const getIcon = (passed) => { if(passed === NodePassed.error) { return { icon :} } return {} }
相信大部分小伙伴,一看到这里,就会知道 原来error的时候,就展示这个图标。
结语写到这里,这篇文章算是结束了。其实文章里的所有代码,相信在座的各位都能写。但只是不知道应该这样写。这篇文章主要是为了教小白写出更漂亮的代码。大神轻点喷!