diff --git a/packages/antd/src/editable/index.tsx b/packages/antd/src/editable/index.tsx index 94209e4337c..c21ea3a355f 100644 --- a/packages/antd/src/editable/index.tsx +++ b/packages/antd/src/editable/index.tsx @@ -1,4 +1,10 @@ -import React, { useLayoutEffect, useRef, useState } from 'react' +import React, { + useEffect, + useMemo, + useLayoutEffect, + useRef, + useState, +} from 'react' import { isVoidField, Field } from '@formily/core' import { useField, observer } from '@formily/react' import { Popover } from 'antd' @@ -17,13 +23,13 @@ type ComposedEditable = React.FC & { Popover?: React.FC } -const useParentPattern = () => { +const useInitialPattern = () => { const field = useField() - return field?.parent?.pattern || field?.form?.pattern + return useMemo(() => field?.pattern, []) } -const useEditable = (): [boolean, (payload: boolean) => void] => { - const pattern = useParentPattern() +const useEditable = (): [boolean, (editable: boolean) => void, () => void] => { + const pattern = useInitialPattern() const field = useField() useLayoutEffect(() => { if (pattern === 'editable') { @@ -36,6 +42,9 @@ const useEditable = (): [boolean, (payload: boolean) => void] => { if (pattern !== 'editable') return field.setPattern(payload ? 'editable' : 'readPretty') }, + () => { + field.setPattern(pattern) + }, ] } @@ -58,15 +67,15 @@ const useFormItemProps = (): IFormItemProps => { } export const Editable: ComposedEditable = observer((props) => { - const [editable, setEditable] = useEditable() - const pattern = useParentPattern() + const [editable, setEditable, resetEditable] = useEditable() + const pattern = useInitialPattern() const itemProps = useFormItemProps() const field = useField() const basePrefixCls = usePrefixCls() const prefixCls = usePrefixCls('formily-editable') const ref = useRef() const innerRef = useRef() - const recover = () => { + const closeEditable = () => { if (ref.current && !field?.errors?.length) { setEditable(false) } @@ -78,9 +87,6 @@ export const Editable: ComposedEditable = observer((props) => { {pattern === 'editable' && ( )} - {pattern !== 'editable' && ( - - )} ) } @@ -99,14 +105,14 @@ export const Editable: ComposedEditable = observer((props) => { if (target?.closest(`.${basePrefixCls}-select-dropdown`)) return if (target?.closest(`.${basePrefixCls}-picker-dropdown`)) return if (target?.closest(`.${basePrefixCls}-cascader-menus`)) return - recover() + closeEditable() }, innerRef) const onClick = (e: React.MouseEvent) => { const target = e.target as HTMLElement const close = innerRef.current.querySelector(`.${prefixCls}-close-btn`) if (target?.contains(close) || close?.contains(target)) { - recover() + closeEditable() } else if (!ref.current) { setTimeout(() => { setEditable(true) @@ -119,6 +125,10 @@ export const Editable: ComposedEditable = observer((props) => { ref.current = editable + useEffect(() => { + return resetEditable + }, []) + return (
@@ -134,7 +144,7 @@ export const Editable: ComposedEditable = observer((props) => { Editable.Popover = observer((props) => { const field = useField() - const pattern = useParentPattern() + const pattern = useInitialPattern() const [visible, setVisible] = useState(false) const prefixCls = usePrefixCls('formily-editable') const closePopover = async () => { diff --git a/packages/next/src/editable/index.tsx b/packages/next/src/editable/index.tsx index b0db3e74a2a..3ff56e145b5 100644 --- a/packages/next/src/editable/index.tsx +++ b/packages/next/src/editable/index.tsx @@ -1,4 +1,10 @@ -import React, { useLayoutEffect, useRef, useState } from 'react' +import React, { + useLayoutEffect, + useMemo, + useEffect, + useRef, + useState, +} from 'react' import { isVoidField, Field } from '@formily/core' import { useField, observer } from '@formily/react' import { Balloon } from '@alifd/next' @@ -21,24 +27,27 @@ type ComposedEditable = React.FC & { Popover?: React.FC } -const useParentPattern = () => { +const useInitialPattern = () => { const field = useField() - return field?.parent?.pattern || field?.form?.pattern + return useMemo(() => field?.pattern, []) } -const useEditable = (): [boolean, (payload: boolean) => void] => { - const pattern = useParentPattern() +const useEditable = (): [boolean, (editable: boolean) => void, () => void] => { + const pattern = useInitialPattern() const field = useField() useLayoutEffect(() => { if (pattern === 'editable') { - field.setPattern('readPretty') + return field.setPattern('readPretty') } }, [pattern]) return [ field.pattern === 'editable', - (pyaload: boolean) => { + (payload: boolean) => { if (pattern !== 'editable') return - field.setPattern(pyaload ? 'editable' : 'readPretty') + field.setPattern(payload ? 'editable' : 'readPretty') + }, + () => { + field.setPattern(pattern) }, ] } @@ -62,15 +71,15 @@ const useFormItemProps = (): IFormItemProps => { } export const Editable: ComposedEditable = observer((props) => { - const [editable, setEditable] = useEditable() - const pattern = useParentPattern() + const [editable, setEditable, resetEditable] = useEditable() + const pattern = useInitialPattern() const itemProps = useFormItemProps() const field = useField() const basePrefixCls = usePrefixCls() const prefixCls = usePrefixCls('formily-editable') const ref = useRef() const innerRef = useRef() - const recover = () => { + const closeEditable = () => { if (ref.current && !field?.errors?.length) { setEditable(false) } @@ -82,9 +91,6 @@ export const Editable: ComposedEditable = observer((props) => { {pattern === 'editable' && ( )} - {pattern !== 'editable' && ( - - )} ) } @@ -101,14 +107,14 @@ export const Editable: ComposedEditable = observer((props) => { useClickAway((e) => { const target = e.target as HTMLElement if (target?.closest(`.${basePrefixCls}-overlay-wrapper`)) return - recover() + closeEditable() }, innerRef) const onClick = (e: React.MouseEvent) => { const target = e.target as HTMLElement const close = innerRef.current.querySelector(`.${prefixCls}-close-btn`) if (target?.contains(close) || close?.contains(target)) { - recover() + closeEditable() } else if (!ref.current) { setTimeout(() => { setEditable(true) @@ -119,6 +125,10 @@ export const Editable: ComposedEditable = observer((props) => { } } + useEffect(() => { + return resetEditable + }, []) + ref.current = editable return ( @@ -136,7 +146,7 @@ export const Editable: ComposedEditable = observer((props) => { Editable.Popover = observer(({ ...props }) => { const field = useField() - const pattern = useParentPattern() + const pattern = useInitialPattern() const [visible, setVisible] = useState(false) const prefixCls = usePrefixCls('formily-editable') const closePopover = async () => {