复盘时间
整理时间
2023-9-28
2023-10-6
代码风格
描述 注释分行问题
- 声明时候的注释全部都放在声明语句的后面(不分行),但是如果声明的时候带上了较长的初始化,那么可以分行
- 函数注释的时候卸载函数的上面
- 约定俗成的注释不写(尽量避免写太多的无用注释,因为代码检查的时候会异常)
示例
javascript
// ---------声明语句----------------
const [selectedRowKeys, setSelectedRowKeys] = useState<string[]>([]); // 存放勾选的每条数据的key值(这种其实就可以不用写,因为antd规定就是这么写的)
const [isModalOpen, setIsModalOpen] = useState(false);// 展示机种料号的弹窗
// 处理打印结果的状态
const [printResultText, setPrintResultText] = useState(
formRef.current?.getFieldValue("result")
)
// ----------函数---------------
// 定义一个函数用来显示弹窗
const showModal = (type: string) => {
if (type === "project") {
// 将表格table的数据清空
getData([])
setColumns(printByProjectIdColumns)
formRef.current?.setFieldsValue({
itemCode: "",
itemName: "",
barcodeRuleName: "",
})
setIsModalOpen(true)
} else {
setColumns(copyPrintColums)
setIsModalOpen(true)
}
setModalType(type)
}
描述 代码分块问题
import
块的顺序- 外部库(包括
antd
,lodash
之类的) React
属性(包括useEffect
,useState
之类的)- 内部文件(在当前文件区的组件,自己封装或者配置文件等)
- 样式文件
- 外部库(包括
- 逻辑区域的顺序
useRef
useState
- 函数
useEffect
- 逻辑区域的代码是分块的,每块之间用空行分隔,每两个函数之间也要空行
- 函数的书写方式,不建议直接写为箭头函数,建议直接用
**function**
示例
javascript
const actionRef = useRef(null);
const childRef = useRef(null);
const [rowData, setRowData] = useState(""); // 进入抽屉弹窗带的行数据
const [highlightData, setHighlightData] = useState({}); // 主表高亮行单行的数据
//-----中间空行-----
// 退料申请
async function clickReturn(record) {
setRowData(record);
childRef.current?.setOpen(true);
}
描述 useEffect书写问题
useEffect
里面写异步函数(async/await
)需要用立即执行函数
包裹起来(x)useEffect
里面可以写.then
示例
javascript
useEffect(() => {
queryTemplateOptions().then(res => {
const arr = res.map((item) => {
return {
value: item.templateId,
label: item.templateName
};
});
setOptions(arr);
});
// 在销毁时,清除定时器
return () => {
clearTimeout(timer.current);
};
}, []);
参考链接:useEffect – React
描述 HTML骨架里的函数问题
- 如果里面的函数(
onClick
之类的)如果只是短短的一行,那么直接写为箭头函数在里面,不要拆出来,变为一个函数放在逻辑区域 - 对应的,骨架里面的函数,不建议写太长,一旦超过了三四行,那么就建议直接提出来放到逻辑区域去写
描述 组件属性问题
组件里面的属性如果有多个(不够一行显示),那么就需要分行(一行一个)
示例
javascript
<ModalTable
columns={columns}
searchData={ModalType === "project" ? getProjectData : searchItemModalData}
visible={isModalOpen}
onVisibleChange={setIsModalOpen}
handleOk={handleOk}
handleCancel={() => setIsModalOpen(false)}
></ModalTable>
描述 命名问题
场景
- 新建和编辑共用一个组件的时候,往往使用
isEdit
(boolean
)来进行判断,不建议使用type
(1,2)来进行判断类型 - 布尔类型:
isXXX
/hasXXX
,模态框的开闭状态,除了只有一个否则不要直接使用open,setOpen
这种 - 函数名字:尽量清晰明了
描述 ts类型问题
场景
- 在
interface
里面尽量少用[key: string]: string | number;
这就相当于any
了,不建议使用这个 - 一些固定的就让
ts
自己推断,不需要自己写 - 如果实在不知道属性类型,可以使用
unknown
而不是any
- 对象里面使用属性可以用
keyOf
,这样就可以不用重复定义
封装风格
描述 批量设置表单中某些属性
INFO
当需要批量设置表单中的某些值的时候,比如需要将某一些数据回填到表单中
场景
当你打开一个模态框选择数据,然后将选择的数据回填到表单里面的时候,因为需要打开多个模态框,选择的数据的字段也不一样,那么如果要回填数据的话,单纯使用fromRef.current.setFieldsValue()
那么一定会出现很多相同的代码
解决方法:
建议将这个设置字段的操作变为一个函数,然后遍历去设置表单的属性值(这边可能会觉得还没有不封装的时候好,因为拿数据的时候,其实拿到了很多的值,但是并不是每一个值我都是需要的)
示例
改变前
javascript
const handleOk = (data: any) => {
// 根据type类型来决定回填的数据
if (ModalType === "project") {
// 由工单号出来的话,带出机种料号,机种名称,计划数量
formRef.current?.setFieldsValue({
bomCode: data[0].bomCode,
bomName: data[0].bomName,
planNumber: data[0].planNumber,
projectId: data[0].projectId
});
} else if (ModalType === "item") {
// 由关键件料号出来的话,带出物料名称,条码规则
setPrintCode(data[0].barcodeRule);
formRef.current?.setFieldsValue({
barcodeRuleName: data[0].barcodeRuleName,
// barcodeRule: data[0].barcodeRule,
itemName: data[0].itemName,
itemCode: data[0].itemCode
});
choseItemCode(data[0].itemCode);
}
// 关闭弹窗
setIsModalOpen(false);
};
改变后
javascript
// 设置表单里面的值
function handleFormData(data: { [key: string]: any; }) {
formRef.current?.setFieldsValue({
...data
});
};
// 处理成功
const handleOk = (data: any) => {
handleFormData(data[0]);
// 根据type类型来决定回填的数据
if (ModalType === "project") {
const { bomCode, bomName, planNumber, projectId } = data[0];
handleFormData({
bomCode,
bomName,
planNumber,
projectId
});
} else if (ModalType === "item") {
const { itemName, barcodeRuleName, itemCode, barcodeRule } = data[0];
setPrintCode(barcodeRule);
handleFormData({
barcodeRuleName,
itemName,
itemCode
});
choseItemCode(data[0].itemCode);
}
// 关闭弹窗
setIsModalOpen(false);
};
描述 模态框的开关闭问题
场景
模态框的打开和关闭的时候,其实做的事情都非常的相似
- 打开:打开一个空的模态框,如果有数据,那么回显
- 关闭:关闭模态框,并且将
modal
里面的数据进行删除(当然你也可以将清除数据放在模态框打开之前,但是我的习惯是,关掉以后就直接清除数据)
这时候我们完全可以将modalOpen
和modalClose
封装起来,到时候直接调用就好了
示例
描述 proTable的columns问题
场景
使用proTable
时建议将columns
抽出来,放到config
文件里面,对于里面的方法可以使用传参传进去
示例
javascript
const columns = [
{
title: "关键件料号",
dataIndex: "itemCode",
key: "itemCode",
},
{
title: "单台数量",
dataIndex: "quantity",
key: "quantity",
},
{
title: "工单需复制数量",
dataIndex: "planNumber",
key: "planNumber",
},
{
title: "已累计复制数量",
dataIndex: "printNumber",
key: "printNumber",
}
]
<Table
columns={columns}
// rowKey的作用是指定表格行的key,可以是字符串或一个函数
dataSource={props.dataSource}
// 为表格第一行添加背景色
rowClassName={(record, index) => {
// 如果当前record里面的关键料号和缓存里面的关键料号相同,就给这一行添加背景色
if (record.itemCode === props.chosedItemCode) {
return 'table-row-color'
} else {
return ''
}
}}
// 省略不重要代码
/>
javascript
改变后
// ---- config文件----
export const columns = [
{
title: "关键件料号",
dataIndex: "itemCode",
key: "itemCode",
},
{
title: "单台数量",
dataIndex: "quantity",
key: "quantity",
},
{
title: "工单需复制数量",
dataIndex: "planNumber",
key: "planNumber",
},
{
title: "已累计复制数量",
dataIndex: "printNumber",
key: "printNumber",
}
]
// ----table文件
<Table
columns={columns}
// rowKey的作用是指定表格行的key,可以是字符串或一个函数
dataSource={props.dataSource}
// 为表格第一行添加背景色
rowClassName={(record, index) => {
// 如果当前record里面的关键料号和缓存里面的关键料号相同,就给这一行添加背景色
if (record.itemCode === props.chosedItemCode) {
return 'table-row-color'
} else {
return ''
}
}}
// 省略不重要代码
/>