Closed melodyWxy closed 1 year ago
hi,正如上述提到的,这是一个微不足道的建议,或者说是关于react组件代码结构规范的一些思考。
背景: 我正在基于ProComponent封装更上层的耦合了业务模型的复用业务组件。
我将组件中胶水层代码的对每个属性的处理,都封装成为了独立的hook,每个文件都没有超过150行,这使得我可以轻易的通过独立的功能hook来找到迭代我的功能的代码区块。
确认功能需求 => 确认对应的prop => 找到对应的hook => 迭代它!或者debugger~
于是单一组件中,我的代码结构是这样子的:
// index.tsx
import React, { useRef, forwardRef, useImperativeHandle, ForwardRefExoticComponent, PropsWithoutRef, RefAttributes } from 'react';
import { ActionType, ProFormInstance, ProTable } from '@ant-design/pro-components';
import { SPFormBase } from '../../../SPForm';
import {
useAddRecordForm,
useAddRecordWrap,
useColumnsProp,
useEditableProp,
usePaginationProp,
useRowKeyProp,
useSearchProp,
useToolBarRender,
} from './effect';
import type { XtableBaseProps, XTableRef } from './type';
export const SPTableBase: ForwardRefExoticComponent<PropsWithoutRef<XtableBaseProps> & RefAttributes<XTableRef>> = forwardRef<XTableRef, XtableBaseProps>(
(
{
autoRowEditConfig,
autoAddRecordConfig,
editable,
search,
pagination,
toolBarRender,
request,
rowKey,
columns,
tableBaseMode,
params,
...otherProps
},
ref,
) => {
// 内置功能处理 - start
const actionRef = useRef<ActionType>();
const queryFormRef = useRef<ProFormInstance>();
// const effectFormRef = useRef()
const { addRecordWrapVisible, setAddRecordWrap } = useAddRecordWrap();
const { mergeRecordFormType, mergeRecordFormColumns } = useAddRecordForm({
recordFormType: autoAddRecordConfig?.recordFormType,
columns,
steps: autoAddRecordConfig?.steps,
});
// 内置功能处理 - end
// 属性封装处理 - start
const mergeSearch = useSearchProp({ search });
const mergeColumns = useColumnsProp({ columns, autoRowEditConfig, rowKey, tableBaseMode });
const mergeEditable = useEditableProp({ editable, actionRef, request, autoRowEditConfig });
const mergePagination = usePaginationProp({ pagination });
const mergeRowKey = useRowKeyProp({ rowKey });
const mergeToolBarRender = useToolBarRender({
toolBarRender,
setAddRecordWrap,
autoAddRecordConfig,
addRecordWrapVisible,
tableBaseMode,
});
// 属性封装处理 - end
// ref转发
useImperativeHandle(ref, () => ({
tableAction: actionRef,
queryForm: queryFormRef,
}));
return (
<>
<ProTable
formRef={queryFormRef}
params={params}
dateFormatter="string"
editable={mergeEditable}
search={mergeSearch}
actionRef={actionRef}
pagination={mergePagination}
cardBordered
toolBarRender={mergeToolBarRender}
request={request}
columns={mergeColumns}
rowKey={mergeRowKey}
{...otherProps}
/>
<SPFormBase
layoutType={mergeRecordFormType}
columns={mergeRecordFormColumns}
visible={addRecordWrapVisible}
drawerProps={
mergeRecordFormType === 'DrawerForm'
? {
title: autoAddRecordConfig?.formTitle || '新增',
destroyOnClose: true,
onClose: () => setAddRecordWrap(false),
}
: undefined
}
modalProps={
mergeRecordFormType === 'ModalForm'
? {
title: autoAddRecordConfig?.formTitle || '新增',
destroyOnClose: true,
onCancel: () => setAddRecordWrap(false),
}
: undefined
}
onFinish={async (values) => {
await autoAddRecordConfig?.onSave(values);
setAddRecordWrap(false);
actionRef.current?.reload();
}}
/>
</>
);
},
);
export default SPTableBase;
或许贵团队有更好的思考和规范,但这仅仅是个建议,期望带给大家更多的思考~
有木有童鞋处理一下呀。
Is this problem fixing?
Is this problem fixing?
no
有木有童鞋处理一下呀。
请问是如何处理这个问题的,我目前也是发现使用了request后就会出现formRef无法使用,去掉request后就正常了。
提问前先看看:
https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md
🐛 bug 描述
嘿,我正在做基于ProComponent封装一套2B的产品解决方案,这显得我很酷。
但在使用BetaSchemaForm组件时,我发现了这样的bug: 当我尝试使用request属性和params属性时,发现当params内含有闭包变量时,会引发formRef的标记丢失。
我仔细排查过,发现使用useState, useRef等返回的闭包变量值时就会引发这个问题。
我做了两个极简的复现demo, 请在下方的复现步骤进行查看:
📷 复现步骤
🏞 期望结果
两次targetRef.current都应该是有值的。但很遗憾如上图所示,ref标记反馈给我的是null。
💻 复现代码
这将引发同样的表现
© 版本信息
🚑 其他信息
我通过其他方式绕过这个bug,解决了我的需求。 但这个bug引发了我的兴趣,于是就在刚才,我开始尝试查看源码以便找到它的来源。 然而很遗憾的是,formRef属性的处理逻辑与太多无关代码耦合到了一起,这使得我的追踪遭遇了阻碍。 我将在下面的评论中建议一种代码结构,这无关bug本身。