/* eslint-disable react-hooks/rules-of-hooks */ /* eslint-disable react-hooks/exhaustive-deps */ import React, { memo, isValidElement, forwardRef, useImperativeHandle, useRef, useMemo, useEffect } from 'react' import { Form } from 'antd' import { random, run, isString, isObject, isFunction, isExist, isNumber, isArray } from '@fexd/tools' import { ConfigProvider } from '@fexd/pro-provider' import { ErrorBoundary } from '@fexd/pro-utils' import { useLatest, useMount, useUnmountedRef } from 'ahooks' import useLocales from '../../locales' import FormItem from '../FormItem' import { ProFieldValueFieldType } from '../../types' import FieldSwitch from './FieldSwitch' import useFormSharedContext from '../formSharedContext' export interface ProFieldProps extends ProFieldValueFieldType { ref?: any } // let renderTimes = 0 // let globalRenderTime = 0 // Object.assign(window, { // getFieldTime() { // return `平均时间:${(globalRenderTime / renderTimes).toFixed(2)}ms,总计渲染次数:${renderTimes}` // }, // }) export const ProField: React.FC = memo( forwardRef(function ProField(props: ProFieldProps = {}, ref: any) { const { form: propForm, ...propField } = props const ctxLocales = useLocales() const withLocales = !!ctxLocales const { sharedFieldProps = {}, groupRegisterMap } = useFormSharedContext() ?? {} const { hook, dependencies, shouldUpdate, group: groupRegisterInfo, formPreserve, ...field } = { ...sharedFieldProps, ...props, } as ProFieldValueFieldType const formPreserveRef = useLatest(formPreserve) const fieldRef = useRef(field) if (isExist(groupRegisterInfo)) { try { const groupList = (isArray(groupRegisterInfo) ? groupRegisterInfo : [groupRegisterInfo]).filter((group) => isString(group), ) as string[] groupList.map((group) => { const currentGroupInfo = groupRegisterMap?.current?.[group] ?? {} const name = (isArray(field?.name) ? field?.name : [field?.name]).join('.') // console.log('currentGroupInfo', field?.name) currentGroupInfo[name] = isArray(field?.name) ? [...field?.name] : field?.name groupRegisterMap.current[group] = currentGroupInfo }) // @ts-ignore propForm.groupRegisterMap = groupRegisterMap.current } catch {} } // const startRenderTime = React.useRef(0) // startRenderTime.current = Date.now() // React.useEffect(() => { // const currentTime = Date.now() // const timeSpend = currentTime - startRenderTime.current // globalRenderTime += timeSpend // renderTimes++ // }) // return '--' useImperativeHandle(ref, () => fieldRef) const rawContent = run(() => { if (isFunction(hook)) { const shouldNotUpdate = dependencies?.length === 0 || shouldUpdate === false return ( false : !dependencies ? true : shouldUpdate} dependencies={shouldNotUpdate ? undefined : dependencies} > {(form, ...args) => { let dynamicField: any = hook({ form } as any, ...args)! if (dynamicField === undefined || dynamicField === true) { dynamicField = {} } fieldRef.current = field const key = dynamicField?.key ?? field?.key const mountedRef = useRef(false) useEffect(() => { mountedRef.current = true return () => { mountedRef.current = false } }, []) // 便于在 hook 内通过改 key 来重置 field 值 useMemo(() => { if (!mountedRef.current) { return } if (formPreserveRef.current === false && field?.preserve !== true && isExist(field?.name)) { form?.resetFields?.([field?.name as any]) } }, [key]) if (!isExist(dynamicField) || dynamicField === false) { return null } if (isValidElement(dynamicField) || isString(dynamicField) || isNumber(dynamicField)) { return dynamicField } if (isObject(dynamicField) && !isValidElement(dynamicField)) { dynamicField = { ...dynamicField } // @ts-ignore delete dynamicField.name // @ts-ignore delete dynamicField.hook const mergedField = { ...field, ...dynamicField, } fieldRef.current = mergedField return } return null }} ) } return }) let content = rawContent ?? ( {rawContent} ) if (!withLocales) { content = {content} } if (!!propForm) { return ( // 指定 form 内部时
{content}
) } return content }), ) export default ProField export { default as EditableProField } from './EditableField' export { default as ReadonlyProField, CopyButton } from './ReadonlyField'